先来探究下浅拷贝
1 a = [1000, [2000, 3000]] 2 b = a.copy() #来个拷贝 3 print(a is b) 4 print(id(a), id(b)) 5 print(id(a[0]) == id(b[0]), id(a[1]) == id(b[1])) #检查第一层每个序列的id是否一致 6 7 #输出结果 8 False #a 与 b 不是同一个 9 4556627912 4557461256 #a b各自id也不一样 10 True True #a b 各自第一层的每个序列的id竟然是一致的 11 12 #难道‘.copy’就是换汤不换药吗?让我们继续实验下去 13 b[1][0] = 9000 # 改变b[1][0]的值 看看有啥变化 14 b[0] = 7000 #再改变b[0]的值 15 print(a, b) 16 print(id(a[0]) == id(b[0]), id(a[1]) == id(b[1]))#再检查第一层每个序列的id是否一致 17 18 #显示结果 19 [1000, [9000, 3000]] [7000, [9000, 3000]] #改变b的第二层列表元素值后,a的第二层列表元素也改变了,相反第一层a的值却没有改变 20 False True #发现各自第一层的id值不一样了,而第二层依然一样
浅拷贝结论:
浅拷贝就像 中药铺偷秘方一样(印度仿制药),仁济堂偷了同仁堂的祖传秘方,核心药效成分的药材照搬不误,换汤不换药,换个药名,就这么卖了,如果仁济堂改良了核心药方,仁济堂还得继续偷。
再来看看深拷贝
1 import copy #导入copy模块 2 c = copy.deepcopy(a) #来个深拷贝 3 print(a is c) #看看a 与c是否是同一个 4 print(a, c) 5 print(id(a), id(c)) 6 print(id(a[0]) == id(c[0]), id(a[1]) == id(c[1]))#检查各a c各层的id是否一致 7 c[1][0] = 8000 #修改c[1][0]的值 8 print(a, c) 9 print(id(a[0]) == id(c[0]), id(a[1]) == id(c[1]))#再检查各a c各层的id是否一致 10 11 #显示结果 12 False #a c不是同一个 13 [1000, [9000, 3000]] [1000, [9000, 3000]] #a c显示结果一样 14 4327133256 4327429064 #a c id不一样 15 True False #a c 第一层id一样 第二层id不一样 16 [1000, [9000, 3000]] [1000, [8000, 3000]] #修改c[1][0]的值后 17 True False #a c 第一层id一样,第二层id不一样
深拷贝结论:
深拷贝 好似 另外一家中药铺 怀仁堂的老板高薪聘请了技术人才(import copy),偷来同仁堂的药方子,把核心药方给技术人才消化吸收,成为怀仁堂自己的知识产权。
以下是官方文件对两者区别的具体说明:
https://docs.python.org/zh-cn/3.7/library/copy.html?highlight=deepcopy#copy.deepcopy
浅层复制和深层复制之间的区别仅与复合对象 (即包含其他对象的对象,如列表或类的实例) 相关: (通俗点说,只要某对象里含有一个嵌套似的对象,那么就会插入这个对象的副本)
- 一个 浅层复制 会构造一个新的复合对象,然后(在可能的范围内)将原对象中找到的 引用 插入其中。
- 一个 深层复制 会构造一个新的复合对象,然后递归地将原始对象中所找到的对象的 副本 插入。
深度复制操作通常存在两个问题, 而浅层复制操作并不存在这些问题:
- 递归对象 (直接或间接包含对自身引用的复合对象) 可能会导致递归循环。
- 由于深层复制会复制所有内容,因此可能会过多复制(例如本应该在副本之间共享的数据)。
原文地址:https://www.cnblogs.com/yydada/p/11700816.html
时间: 2024-11-13 09:46:42