1. python copy实现浅拷贝,deepcopy实现深拷贝
通俗的理解:浅拷贝只拷贝父对象,不拷贝父对象内部的子对象;深拷贝不仅考虑父对象,还考虑父对象内部的子对象。
示例:list5是origin的浅拷贝,list6是origin的深拷贝。两者分别都拷贝了父对象,即origin, list5, list6的id不一样,说明list5和list6分别将父对象origin拷贝了一份。但是 id(list5[1]) = id(origin[1]),说明list5和origin第一索引指向同一个对象,并没有实现拷贝;id(list6[1]) != id(origin[1]),说明说明list6和origin第一索引指向不同的列表,两者取值相同,是因为实现了子对象拷贝,深拷贝时将origin的子对象也拷贝了一份。
from copy import deepcopy,copy
a = [1,2,3]
origin = [0,a,9]
list5 = copy(origin)
list6 = deepcopy(origin)
print(id(origin),id(list5),id(list6))
print(id(origin[1]),id(list5[1]),id(list6[1]))
2537439441992 2537439470728 2537439482888
2537439260808 2537439260808 2537438551048
2. 相关操作实例:
(1) list5, list6和origin的id不一样,修改list5和list6中的不可变对象,不会影响origin.
list5[2] = 3 # 修改列表中的不可变对象
print(list5)
print(origin)
list6[2] = 7 # 修改列表中的不可变对象
print(list6)
print(origin)
[0, [1, 2, 3], 3]
[0, [1, 2, 3], 9]
[0, [1, 2, 3], 7]
[0, [1, 2, 3], 9]
(2)由于list5[1]和origin[1]指向同一个列表,故修改list5[1]会影响origin; 而list6实现了深拷贝,list6[1]和origin[1]是两个id不同的列表,故修改list6[1]不会影响origin[1]。
list5[1][1] = 0 # 修改列表中的可变对象
print(list5)
print(origin)
[0, [1, 0, 3], 3]
[0, [1, 0, 3], 9]
list6[1][1] = 100 #修改类表中的可变对象
print(list6)
print(origin)
[0, [1, 100, 3], 7]
[0, [1, 0, 3], 9]
3. 等号,列表切片和object.copy()拷贝探索:
由以下示例可知等号赋值不涉及拷贝,list1和origin是完全相同的对象(id一样),列表切片和object.copy()都是浅拷贝。
origin = [0,a,9]
list1 = origin
list2 = origin[:]
list3 = origin[::]
list4 = origin.copy()
print(id(origin),id(list1),id(list2),id(list3),id(list4))
print(id(origin[1]),id(list1[1]),id(list2[1]),id(list3[1]),id(list4[1]))
2537439482888 2537439482888 2537439414856 2537439222152 2537439222792
2537439413768 2537439413768 2537439413768 2537439413768 2537439413768