找回密码
 立即注册
首页 业界区 安全 4.7 浅拷贝和深拷贝(只针对可变类型:列表、字典、集合 ...

4.7 浅拷贝和深拷贝(只针对可变类型:列表、字典、集合)

袂沐 2025-8-12 18:27:19
4.7 浅拷贝和深拷贝(只针对可变类型:列表、字典、集合)
  1. # 拷贝
  2. lis1=[1,2,3,[4,5]] #可变:值变id不变
  3. lis2=lis1 #最基本拷贝
  4. print(f'操作前:id(lis1):{id(lis1)},lis1:{lis1}')
  5. print(f'操作前:id(lis2):{id(lis2)},lis2:{lis2}')
  6. print('-'*50)
  7. lis1.append(5) #修改lis1,lis2也被修改
  8. print(lis1)
  9. print(lis2)
  10. print('-'*50)
  11. lis1[0]=0#修改lis1,lis2也被修改
  12. print(lis1)
  13. print(lis2)
  14. print('-'*50)
  15. lis1[0]=0#修改lis1,lis2也被修改
  16. print(lis1)
  17. print(lis2)
  18. print('-'*50)
  19. lis1[3].append(6)
  20. print(lis1)
  21. print(lis2)
  22. print('-'*50)
  23. print(f'操作后:id(lis1):{id(lis1)},lis1:{lis1}')
  24. print(f'操作后:id(lis2):{id(lis2)},lis2:{lis2}')
复制代码
  1. 操作前:id(lis1):2658013585664,lis1:[1, 2, 3, [4, 5]]
  2. 操作前:id(lis2):2658013585664,lis2:[1, 2, 3, [4, 5]]
  3. --------------------------------------------------
  4. [1, 2, 3, [4, 5], 5]
  5. [1, 2, 3, [4, 5], 5]
  6. --------------------------------------------------
  7. [0, 2, 3, [4, 5], 5]
  8. [0, 2, 3, [4, 5], 5]
  9. --------------------------------------------------
  10. [0, 2, 3, [4, 5], 5]
  11. [0, 2, 3, [4, 5], 5]
  12. --------------------------------------------------
  13. [0, 2, 3, [4, 5, 6], 5]
  14. [0, 2, 3, [4, 5, 6], 5]
  15. --------------------------------------------------
  16. 操作后:id(lis1):2658013585664,lis1:[0, 2, 3, [4, 5, 6], 5]
  17. 操作后: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中对应元素改变
  1. import copy
  2. lis1=[1,2,[3,4],6,7,8]
  3. lis2=copy.copy(lis1) #将lis1拷贝给lis2
  4. lis1.append(9)
  5. print(f'lis1:{lis1}') #lis1改变
  6. print(f'lis2:{lis2}') #lis2不变
  7. print('-'*50)
  8. print(lis1[2])
  9. lis1[2].append(5)
  10. print(f'lis1:{lis1}') #lis1改变
  11. print(f'lis2:{lis2}') #lis2也改变
  12. # lis1[2]元素类型是列表,是可变类型,因此值改变,内存地址没有变。
  13. # lis2[2]与lis1[1]指向了同一内存地址,任意修改lis1[1] or lis2[1],另一元素都跟着改变。
复制代码
  1. lis1:[1, 2, [3, 4], 6, 7, 8, 9]
  2. lis2:[1, 2, [3, 4], 6, 7, 8]
  3. --------------------------------------------------
  4. [3, 4]
  5. lis1:[1, 2, [3, 4, 5], 6, 7, 8, 9]
  6. lis2:[1, 2, [3, 4, 5], 6, 7, 8]
复制代码
  1. #在内存当中,列表存储索引对应变量值的地址
  2. lis1[0]=0
  3. #元素lis[0]是不可变类型;修改值,内存地址改变
  4. print('列表lis1每个元素的内存地址')
  5. for i in range(len(lis1)):
  6.     print(id(lis1[i]))
  7. print('-'*50)
  8. print('列表lis2每个元素的内存地址')
  9. for i in range(len(lis2)):
  10.     print(id(lis2[i]))
  11. #lis[0]为不可变类型,值变,id改变。因此lis1[1]被修改了,lis2[1]内存地址不变,因此未被修改。
复制代码
  1. 列表lis1每个元素的内存地址
  2. 140727203342744
  3. 140727203342808
  4. 2658013318784
  5. 140727203342936
  6. 140727203342968
  7. 140727203343000
  8. 140727203343032
  9. --------------------------------------------------
  10. 列表lis2每个元素的内存地址
  11. 140727203342776
  12. 140727203342808
  13. 2658013318784
  14. 140727203342936
  15. 140727203342968
  16. 140727203343000
复制代码
4.7.2 深拷贝
  1. import copy
  2. lis1=[1,2,[3,4],6,7,8]
  3. lis2=copy.deepcopy(lis1)
  4. print('列表lis1每个元素的内存地址')
  5. for i in range(len(lis1)):
  6.     print(id(lis1[i]))
  7. print('-'*50)
  8. print('列表lis2每个元素的内存地址')
  9. for i in range(len(lis2)):
  10.     print(id(lis2[i]))
  11. #两个列表可变类型元素内存地址相同,不可变类型元素内存地址元素不同。
复制代码
  1. 列表lis1每个元素的内存地址
  2. 140727203342776
  3. 140727203342808
  4. 2658013591680
  5. 140727203342936
  6. 140727203342968
  7. 140727203343000
  8. --------------------------------------------------
  9. 列表lis2每个元素的内存地址
  10. 140727203342776
  11. 140727203342808
  12. 2657998541696
  13. 140727203342936
  14. 140727203342968
  15. 140727203343000
复制代码
  1. #不可变类型元素内存地址不同,所以深拷贝修改一个列表不会影响另一个列表
  2. lis1=[1,2,[3,4],6,7,8]
  3. lis2=copy.deepcopy(lis1)
  4. lis1[0]=0
  5. print(lis1)
  6. print(lis2)
  7. print('-'*50)
  8. lis1[2].append(5)
  9. print(lis1)
  10. print(lis2)
复制代码
  1. [0, 2, [3, 4], 6, 7, 8]
  2. [1, 2, [3, 4], 6, 7, 8]
  3. --------------------------------------------------
  4. [0, 2, [3, 4, 5], 6, 7, 8]
  5. [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都不变。


来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册