浅拷贝(Shallow Copy)与深拷贝(Deep Copy)的区别?copy.copy与copy.deepcopy()输出为何一致?
浅拷贝与深拷贝的核心区别:看嵌套对象的引用
你觉得copy.copy()和copy.deepcopy()输出一致,本质是只观察了表层不可变数据的表现——当对象没有嵌套结构时,两者的差异确实不会显性体现,但一旦涉及可变嵌套对象,区别立刻就能显现。
1. 非嵌套对象:看似效果一致
对于没有嵌套的简单对象(比如只包含int、str等不可变类型的列表),浅拷贝和深拷贝都会生成新的外层容器,而内部不可变元素的引用不会带来实际差异:
import copy a = [1, "hello", 3] b = copy.copy(a) c = copy.deepcopy(a) print(b == c) # 输出 True,表层数据完全相同 print(b is c) # 输出 False,外层容器内存地址不同
这里因为内部元素是不可变类型,即使共享引用,也不会出现一方修改影响另一方的情况,所以看起来效果一样。
2. 嵌套可变对象:差异显性化
当对象包含可变嵌套结构(比如列表套列表、字典套字典)时,浅拷贝和深拷贝的本质区别就会暴露:
import copy # 原对象包含嵌套可变列表 a = [1, [2, 3]] b = copy.copy(a) # 浅拷贝 c = copy.deepcopy(a) # 深拷贝 # 修改原对象的嵌套列表 a[1].append(4) print(b) # 输出 [1, [2, 3, 4]] —— 浅拷贝的嵌套列表和原对象共享引用,被同步修改 print(c) # 输出 [1, [2, 3]] —— 深拷贝递归复制了嵌套列表,完全独立于原对象
3. 用内存地址验证引用关系
可以通过id()函数查看元素的内存地址,明确引用差异:
print(id(a[1])) # 原嵌套列表的内存地址 print(id(b[1])) # 和原地址完全一致,浅拷贝共享嵌套对象的引用 print(id(c[1])) # 全新的内存地址,深拷贝生成了独立的嵌套对象
总结
- 浅拷贝(
copy.copy):仅复制外层容器,内部的可变元素直接引用原对象的对应元素,共享内存地址 - 深拷贝(
copy.deepcopy):复制外层容器的同时,递归复制所有嵌套的可变对象,所有层级的对象都是完全独立的新实例
内容的提问来源于stack exchange,提问作者KAVYA SHARMA
相关产品推荐
相关产品推荐

