Python基础滚固(六)深浅拷贝的趣谈

时间:2019-10-18
本文章向大家介绍Python基础滚固(六)深浅拷贝的趣谈,主要包括Python基础滚固(六)深浅拷贝的趣谈使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

先来探究下浅拷贝

 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