4.7 浅拷贝和深拷贝(只针对可变类型:列表、字典、集合)
- # 拷贝
- lis1=[1,2,3,[4,5]] #可变:值变id不变
- lis2=lis1 #最基本拷贝
- print(f'操作前:id(lis1):{id(lis1)},lis1:{lis1}')
- print(f'操作前:id(lis2):{id(lis2)},lis2:{lis2}')
- print('-'*50)
- lis1.append(5) #修改lis1,lis2也被修改
- print(lis1)
- print(lis2)
- print('-'*50)
- lis1[0]=0#修改lis1,lis2也被修改
- print(lis1)
- print(lis2)
- print('-'*50)
- lis1[0]=0#修改lis1,lis2也被修改
- print(lis1)
- print(lis2)
- print('-'*50)
- lis1[3].append(6)
- print(lis1)
- print(lis2)
- print('-'*50)
- print(f'操作后:id(lis1):{id(lis1)},lis1:{lis1}')
- print(f'操作后:id(lis2):{id(lis2)},lis2:{lis2}')
复制代码- 操作前:id(lis1):2658013585664,lis1:[1, 2, 3, [4, 5]]
- 操作前:id(lis2):2658013585664,lis2:[1, 2, 3, [4, 5]]
- --------------------------------------------------
- [1, 2, 3, [4, 5], 5]
- [1, 2, 3, [4, 5], 5]
- --------------------------------------------------
- [0, 2, 3, [4, 5], 5]
- [0, 2, 3, [4, 5], 5]
- --------------------------------------------------
- [0, 2, 3, [4, 5], 5]
- [0, 2, 3, [4, 5], 5]
- --------------------------------------------------
- [0, 2, 3, [4, 5, 6], 5]
- [0, 2, 3, [4, 5, 6], 5]
- --------------------------------------------------
- 操作后:id(lis1):2658013585664,lis1:[0, 2, 3, [4, 5, 6], 5]
- 操作后:id(lis2):2658013585664,lis2:[0, 2, 3, [4, 5, 6], 5]
复制代码 4.7.1 浅拷贝
- lis1=[1,2,[3,4],6,7,8]
- lis2=copy.copy(lis1)
- 修改lis1中不可变类型(如整型),lis2中对应元素不改变
- 修改lis1中可变类型(如列表),lis2中对应元素改变
- import copy
- lis1=[1,2,[3,4],6,7,8]
- lis2=copy.copy(lis1) #将lis1拷贝给lis2
- lis1.append(9)
- print(f'lis1:{lis1}') #lis1改变
- print(f'lis2:{lis2}') #lis2不变
- print('-'*50)
- print(lis1[2])
- lis1[2].append(5)
- print(f'lis1:{lis1}') #lis1改变
- print(f'lis2:{lis2}') #lis2也改变
- # lis1[2]元素类型是列表,是可变类型,因此值改变,内存地址没有变。
- # lis2[2]与lis1[1]指向了同一内存地址,任意修改lis1[1] or lis2[1],另一元素都跟着改变。
复制代码- lis1:[1, 2, [3, 4], 6, 7, 8, 9]
- lis2:[1, 2, [3, 4], 6, 7, 8]
- --------------------------------------------------
- [3, 4]
- lis1:[1, 2, [3, 4, 5], 6, 7, 8, 9]
- lis2:[1, 2, [3, 4, 5], 6, 7, 8]
复制代码- #在内存当中,列表存储索引对应变量值的地址
- lis1[0]=0
- #元素lis[0]是不可变类型;修改值,内存地址改变
- print('列表lis1每个元素的内存地址')
- for i in range(len(lis1)):
- print(id(lis1[i]))
- print('-'*50)
- print('列表lis2每个元素的内存地址')
- for i in range(len(lis2)):
- print(id(lis2[i]))
- #lis[0]为不可变类型,值变,id改变。因此lis1[1]被修改了,lis2[1]内存地址不变,因此未被修改。
复制代码- 列表lis1每个元素的内存地址
- 140727203342744
- 140727203342808
- 2658013318784
- 140727203342936
- 140727203342968
- 140727203343000
- 140727203343032
- --------------------------------------------------
- 列表lis2每个元素的内存地址
- 140727203342776
- 140727203342808
- 2658013318784
- 140727203342936
- 140727203342968
- 140727203343000
复制代码 4.7.2 深拷贝
- import copy
- lis1=[1,2,[3,4],6,7,8]
- lis2=copy.deepcopy(lis1)
- print('列表lis1每个元素的内存地址')
- for i in range(len(lis1)):
- print(id(lis1[i]))
- print('-'*50)
- print('列表lis2每个元素的内存地址')
- for i in range(len(lis2)):
- print(id(lis2[i]))
- #两个列表可变类型元素内存地址相同,不可变类型元素内存地址元素不同。
复制代码- 列表lis1每个元素的内存地址
- 140727203342776
- 140727203342808
- 2658013591680
- 140727203342936
- 140727203342968
- 140727203343000
- --------------------------------------------------
- 列表lis2每个元素的内存地址
- 140727203342776
- 140727203342808
- 2657998541696
- 140727203342936
- 140727203342968
- 140727203343000
复制代码- #不可变类型元素内存地址不同,所以深拷贝修改一个列表不会影响另一个列表
- lis1=[1,2,[3,4],6,7,8]
- lis2=copy.deepcopy(lis1)
- lis1[0]=0
- print(lis1)
- print(lis2)
- print('-'*50)
- lis1[2].append(5)
- print(lis1)
- print(lis2)
复制代码- [0, 2, [3, 4], 6, 7, 8]
- [1, 2, [3, 4], 6, 7, 8]
- --------------------------------------------------
- [0, 2, [3, 4, 5], 6, 7, 8]
- [1, 2, [3, 4], 6, 7, 8]
复制代码
- 总结:
- 拷贝:lis2=lis1,lis1内部所有对象发生改变,lis2都跟着改变。
- 浅拷贝:lis2=copy.copy(lis1),lis1内部不可变对象发生改变,lis2不变;lis1内部可变对象发生改变,lis2改变。
- 深拷贝:lis2=copy.deepcopy(lis1),lis1内部所有对象发生改变,lis2都不变。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |