借花献佛
转载的文章,
https://www.jianshu.com/p/55db812f7f0a
https://www.jianshu.com/p/75a8b01d7899
从这2个作者聊到的 深复制,浅复制谈起,我自己学到很多东西,非常感谢
另外总计一下,继续学习
总结
(1) 直接赋值=,那就是指针指向对象而已
(2) 浅复制 shallow copy :
(3) 深复制 deep copy :
复制操作1
obj.copy()
obj.deepcopy()
复制操作2
import copy
copy.copy()
copy.deepcopy()
原理
都是指向对象的
(1) python其实没有变量,这些"变量 variables "其实都是 "标签" tag
( 标签tag用来给obj 贴上去, just a name,not obj itself)
(2) python 没有"赋值",其实都是 引用
(3) 赋值的时候发生了什么:
如 listA1=[1,2,3]
listA2=[4,5,6]
1 首先创建了一个[1,2,3]的list的obj
2 赋值打标签:把listA1 贴给这个obj
3 创建新列表对象[4,5,6]
4 再赋值打标签:把listA1 贴给新的obj
5 老的[1,2,3]怎么办?有python的垃圾回收机制处理
实测
直观差别
赋值:两者关联改动,listB=listA
浅复制:第一层,两者独立,方法1:使用copy()方法:listB=listA.copy()
方法2:使用切片操作 listB=listA[:] 或 listB=[0:len(listA)+1]
深复制:完全独立,指向不同的对象
>>> import copy
>>> listA=[[1,2,3],4,5,6]
>>> listB=listA
>>> listC=listA.copy()
>>> listD=copy.deepcopy(listA)
>>> listA[-1]=999
>>> listA[0][0]=888
>>> listA
[[888, 2, 3], 4, 5, 999]
>>> listB
[[888, 2, 3], 4, 5, 999]
>>> listC
[[888, 2, 3], 4, 5, 6]
>>> listD
[[1, 2, 3], 4, 5, 6]
>>>
直接赋值
因为直接赋值会导致两个变量,关联,都指向同一个obj
无论哪个变量变化了,都会一起改变
但是如果某一个变量被重新赋值了---重新指向给了另外一个对象,那么2个变量就不指向同一个obj了
2个变量分别指向了2个obj,意味着两个obj任何变化,也都只影响对应的1个变量了
>>> listC1=[1,2,3]
>>> listC2=listC1
>>> print(listC1,listC2)
[1, 2, 3] [1, 2, 3]
>>> listC1[0]="A"
>>> print(listC1,listC2)
['A', 2, 3] ['A', 2, 3]
>>> listC1=[4,5,6]
>>> print(listC1,listC2)
[4, 5, 6] ['A', 2, 3]
>>> listC1[0]="B"
>>> print(listC1,listC2)
['B', 5, 6] ['A', 2, 3]
为什么会导致循环?
因为用的直接赋值--引用,会导致自己的某个 index 又指向自己
>>> listA1=[1,2,3]
>>> listA1[1]=listA1
>>> listA1
[1, [...], 3]
转的这个图,我始终觉得有点问题,或者是没看懂,因为对象不应该指自己,而是index指着对象啊,这个图有点混淆?
避免这种循环的办法--浅复制
>>> listA1=[1,2,3]
>>> listA1[0]=listA1[:]
>>> listA1
[[1, 2, 3], 2, 3]
>>> listA1=[1,2,3]
>>> listA1[2]=listA1.copy()
>>> listA1
[1, 2, [1, 2, 3]]
多层时,非第1层外,浅复制会出错
>>> listB1=[[1,2,3],2,3]
>>> listB1
[[1, 2, 3], 2, 3]
>>> listB2=listB1.copy()
>>> listB1[0][0]="a"
>>> listB1[2]="b"
>>> listB1
[['a', 2, 3], 2, 'b']
>>> listB2
[['a', 2, 3], 2, 3]
>>>