先看这三个词的意思我觉得菜鸟的总结就很好 Python 直接赋值、浅拷贝和深度拷贝 | 菜鸟教程
直接赋值:其实就是对象的引用(别名)。
浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。
深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。
有一天我遇到这样一个问题,大概是这样给一个list变成list[dict](就是list的每个值加一个描述字段的key)。
a=['a','b','c','d']
b={}
c=[]
for i in a:
b["info"]=i
c.append(b)
print(c)
我们看一下程序的逻辑,for循环a,然后b是一个字典,那么b每次被赋值然后被append到 c这个list里,按照预想 c应该打印出
[{'info': 'a'}, {'info': 'b'}, {'info': 'c'}, {'info': 'd'}]
但是并没有,运行下面的程序会得到
[{'info': 'd'}, {'info': 'd'}, {'info': 'd'}, {'info': 'd'}]
这是为什么呢,先说怎么解决这个问题,我们引入拷贝这个概念,把代码改成这样,就得到了我们想要的
a=['a','b','c','d']
b={}
c=[]
for i in a:
b["info"]=i
f = b.copy()
c.append(f)
print(c)
[{'info': 'a'}, {'info': 'b'}, {'info': 'c'}, {'info': 'd'}]
因为XXX.copy()这个函数是浅拷贝,浅拷贝就是重新分配一块内存,创建一个新的对象,但里面的元素是原对象中各个子对象的引用。
相较于普通的赋值,浅拷贝会将两个变量分别放在不同的内存地址,解决了直接赋值的缺点
但是如果我们这个数据结构不是一层的怎么办呢,那就要用到深拷贝。copy.deepcopy()
深拷贝,是指重新分配一块内存,创建一个新的对象,并且将原对象中的元素,以递归的方式,通过创建新的子对象拷贝到新对象中。因此,新对象和原对象没有任何关联。
使用方法:
#直接赋值
a=1
b=a #它俩内存地址是一样的
#浅拷贝
a={'a':[1,2,3]}
b=a.copy()
#他两地址不一样了 但是[1,2,3]是同一个
#深拷贝
a={'a':[1,2,3]}
b=copy.deepcopy(a)
#这是两个完全独立的东西了
用图直观的描述三者的区别
直接赋值
浅拷贝
深拷贝:
所以在写python程序的时候,遇到复杂的数据结构,要考虑该用深拷贝还是用等号赋值。