基本类型
参考博文:https://www.cnblogs.com/miaomiaokaixin/p/11497813.html
以下进行简单概括,具体细节请阅读上述博文
六种数据类型分类
不可变数据(3个):Number、String、Tuple
可变数据(3个):List、Dictionary、Set
python赋值(=):数据完全共享(博文中有例子说明,很清晰)
赋值是在内存中指向同一个对象:
如果是可变(mutable)类型,比如列表、字典、集合,修改其中一个,另一个必定改变
如果是不可变类型(immutable),比如数字、字符串、元组,修改了其中一个,另一个并不会变
python浅拷贝(博文中有例子和图解)
1.浅拷贝:数据半共享(拷贝第一层的数据,具有自己单独的内存地址;嵌套层即第二层或其他层不拷贝,指向原有的内存地址)
2.原则
只复制一层,他变我不变;其余层,他变我也变。
如果只有一层,就相当于深拷贝了
3.方法-三种
第一种:a = b[:]
第二种:a = b.copy()
第三种:引用copy模块,import copy | a = copy.copy(b)
python深拷贝(博文中有例子和图解)
1.深拷贝:数据完全不共享(复制其数据完完全全放独立的一个内存,完全拷贝,数据不共享)
2.原则
他变我也变。
3.方法
引用copy模块,import copy | a = copy.deepcopy(b)
补充:
除了基本类型, 我总结下我常用的数据类型:
可变数据:array, tensor
1.numpy.array
>>> import numpy as np
>>>
>>> a = np.array([[1, 3, 2], [3,2, 1], [7, 8, 9]])
>>> a
array([[1, 3, 2],
[3, 2, 1],
[7, 8, 9]])
b = a
>>> b
array([[1, 3, 2],
[3, 2, 1],
[7, 8, 9]])
>>> a[1, 0] = 10 #相同地址的一个变量修改, b也发生变化
>>> a
array([[ 1, 3, 2],
[10, 2, 1],
[ 7, 8, 9]])
>>> b
array([[ 1, 3, 2],
[10, 2, 1],
[ 7, 8, 9]])
>>> c = b.copy() #此时已经是深拷贝了, b变c不变,使用deepcopy也可完成深拷贝
>>> b
array([[ 1, 3, 2],
[10, 2, 1],
[ 7, 8, 9]])
>>> c
array([[ 1, 3, 2],
[10, 2, 1],
[ 7, 8, 9]])
>>> b[1, 0] = 100
>>> b
array([[ 1, 3, 2],
[100, 2, 1],
[ 7, 8, 9]])
>>> c
array([[ 1, 3, 2],
[10, 2, 1],
[ 7, 8, 9]])
2.tensor
tensor与numpy一样,是可变数据类型, 但实现深拷贝的方式是使用copy模块中的deepcopy()
id()、is、==
id()
查看当前变量的地址值,注意如果同样赋值为1, 可能对应的地址是不相等的, 因为可能分配了不同的地址
另, id不同也可能是浅拷贝,如list使用.copy()、copy()时id不同,但是是浅拷贝,代码如下
>>> a = [[1, 2, 3, 4], [3, 4, 1, 5]]
>>> b = a
>>> c = a.copy()
>>> d = copy(a)
>>> e = deepcopy(a)
>>> id(a) == id(b) #判断地址是否相同
True
>>> id(a) == id(c)
False
>>> id(a) == id(d)
False
>>> id(a) == id(e)
False
>>> a[0][0] = 100 #修改值
>>> a
[[100, 2, 3, 4], [3, 4, 1, 5]]
>>> b
[[100, 2, 3, 4], [3, 4, 1, 5]] #c、d 与a地址不同,但是a变c、d也变化
>>> c
[[100, 2, 3, 4], [3, 4, 1, 5]]
>>> d
[[100, 2, 3, 4], [3, 4, 1, 5]]
>>> e #e是深拷贝,没有变化
[[1, 2, 3, 4], [3, 4, 1, 5]]
is
判断id是否相等
==
判断值是否相等
>>> a = np.array([[1, 3, 2], [3,2, 1], [7, 8, 9]])
>>> a = torch.tensor(a)
>>> b = a
>>> id(a)
140045026533664
>>> id(b)
140045026533664
>>> c = deepcopy(a) #深拷贝
>>> id(c)
140045026533592
>>> d = a
>>> id(d)
140045026533664
>>> id(d)
140045026533664
>>> id(a)
140045026533664
>>> a is d
True
>>> a is c #c是深拷贝, id 不相等
False
>>> c is b #c是深拷贝, id 不相等
False
>>> b is a
True
>>> b is d
True
>>> c == b #id不同,但值相同
tensor([[True, True, True],
[True, True, True],
[True, True, True]])
过程讲解
参考博文:https://blog.csdn.net/hohaizx/article/details/78427406
赋值
首先需要明确的是,Python中一切事物皆对象,变量是对对象在内存中的存储和地址的抽象。
“=”(赋值号)是将右侧对象的内存地址赋值给左侧的变量。
当我们写下面语句时:
a = “abc”
1
Python解释器其实顺序干了两件事情:
1、在内存中创建一个字符串“abc”;
2、在内存中创建一个名为“a”的变量,并将“a”指向字符串“abc”(将“abc”的地址保存到“a”中)。
这样我们就能通过操作“a”而改变内存中的“abc”。
所以执行下面语句
a = “123”
b = a
a = “xyz”
1
2
3
执行第一句Python解释器创建字符串“123”和变量“a”,并把“a”指向“123”。
执行第二句,因为“a”已经存在,并不会创建新的对象,但会创建变量“b”,并把“b”指向“a”指向的字符串“123“。
执行第三句,首先会创建字符串“xyz”,然后把“xyz”的地址赋予“a“(“a”指向字符串“xyz”)。
我们可以通过调用id()方法查看变量所指向对象在内存中的地址。
a = “123”
id(a) # 2248238011648,这个数字就代表了a所指向的对象在内存中地址