Python 面试常考:浅拷贝与深拷贝的区别详解
在 Python 面试中,浅拷贝(shallow copy) 和 深拷贝(deep copy) 是非常高频的考点。很多初学者在操作列表、字典等可变对象时,常常因为没有理解拷贝的本质而掉坑。本文将通过实例带你彻底弄清浅拷贝与深拷贝的区别,以及它们在面试中的常见陷阱。
一、赋值 vs 浅拷贝 vs 深拷贝
在 Python 中,变量存放的其实是对象的引用(指针)。所以:
赋值(=):只是增加一个引用,两个变量指向同一块内存。
浅拷贝(copy.copy):创建一个新对象,但内部元素依然是原对象的引用。
深拷贝(copy.deepcopy):递归复制对象及其子对象,完全独立。
二、浅拷贝示例
import copy
# 原始数据
list1 = [[1, 2], [3, 4]]
# 浅拷贝
list2 = copy.copy(list1)
# 修改内部元素
list2[0][0] = 99
print("list1:", list1) # [[99, 2], [3, 4]]
print("list2:", list2) # [[99, 2], [3, 4]]
可以看到,浅拷贝只复制了最外层的对象,内部嵌套对象还是共享的,因此修改 list2 也会影响 list1。
三、深拷贝示例
import copy
# 原始数据
list1 = [[1, 2], [3, 4]]
# 深拷贝
list2 = copy.deepcopy(list1)
# 修改内部元素
list2[0][0] = 99
print("list1:", list1) # [[1, 2], [3, 4]]
print("list2:", list2) # [[99, 2], [3, 4]]
此时,list2 是一个完全独立的副本,修改不会影响 list1。
四、常见应用场景
浅拷贝适用场景
当对象结构简单,或只关心最外层时,浅拷贝足够。
例如复制一个普通列表 [1, 2, 3]。
深拷贝适用场景
当对象嵌套复杂,且需要完全隔离副本时,必须用深拷贝。
例如嵌套列表、嵌套字典、树形数据结构。
五、面试常见陷阱
1. list 的赋值与浅拷贝
a = [1, 2, 3]
b = a # 引用同一个对象
c = a[:] # 浅拷贝(等价于 copy.copy)
b[0] = 99
print(a) # [99, 2, 3]
print(c) # [1, 2, 3]
👉 面试常问:b 和 c 有什么区别?
2. 浅拷贝对嵌套结构无效
a = [[1, 2], [3, 4]]
b = a[:]
b[0][0] = 99
print(a) # [[99, 2], [3, 4]]
👉 考点:浅拷贝只复制第一层引用。
3. 深拷贝的性能问题
深拷贝需要递归复制整个对象,性能比浅拷贝差。
面试中可能会问:什么时候不建议使用深拷贝?
答:当数据量很大且不需要完全隔离时,不建议用深拷贝。
六、总结
=:赋值,多个变量指向同一个对象。
copy.copy():浅拷贝,复制对象本身,但内部嵌套对象还是共享的。
copy.deepcopy():深拷贝,递归复制所有层级,完全独立。
面试高频问法:
Python 中 list[:] 和 copy.copy() 的区别?
为什么浅拷贝会影响原对象?
深拷贝什么时候可能影响性能?
掌握浅拷贝与深拷贝,不仅能避免日常开发中的“共享数据陷阱”,更能帮助你在面试中答出亮点答案。