浅拷贝 vs. 深拷贝
在理解 deepcopy 之前,必须先明白它与 copy()(浅拷贝)的区别,这个区别主要体现在当字典包含可变对象(如列表、字典、集合等)时。

浅拷贝 (dict.copy() 或 copy.copy())
浅拷贝会创建一个新的字典对象,但是这个新字典中的元素(键值对)是对原字典中元素的引用。
- 对于不可变对象(如数字、字符串、元组):因为它们的内容不能被修改,所以看起来就像是“复制”了。
- 对于可变对象(如列表、字典):新字典中的可变对象和原字典中的是同一个对象,修改这个可变对象,会同时影响到原字典和拷贝后的字典。
示例代码:
# 原始字典
original_dict = {
'name': 'Alice',
'scores': [88, 92, 76],
'info': {'city': 'New York'}
}
# 使用 .copy() 进行浅拷贝
shallow_copied_dict = original_dict.copy()
# 修改不可变对象 'name'
shallow_copied_dict['name'] = 'Bob'
print(f"Original name: {original_dict['name']}") # 输出: Original name: Alice
print(f"Copied name: {shallow_copied_dict['name']}") # 输出: Copied name: Bob
# 不可变对象的修改互不影响,符合预期。
# 修改可变对象 'scores' 中的元素
shallow_copied_dict['scores'].append(100)
print("\nAfter modifying 'scores' list:")
print(f"Original scores: {original_dict['scores']}") # 输出: Original scores: [88, 92, 76, 100]
print(f"Copied scores: {shallow_copied_dict['scores']}") # 输出: Copied scores: [88, 92, 76, 100]
# 可变对象的修改影响了原字典!这就是浅拷贝的关键。
# 修改嵌套的可变对象 'info'
shallow_copied_dict['info']['city'] = 'Boston'
print("\nAfter modifying nested 'info' dict:")
print(f"Original info: {original_dict['info']}") # 输出: Original info: {'city': 'Boston'}
print(f"Copied info: {shallow_copied_dict['info']}") # 输出: Copied info: {'city': 'Boston'}
# 嵌套的可变对象的修改也影响了原字典!
深拷贝 (copy.deepcopy())
深拷贝会创建一个全新的字典对象,并且递归地复制这个字典中所有的可变对象,使得新字典中的所有元素都与原字典完全独立,修改深拷贝后的字典中的任何元素,都不会影响到原字典。
如何使用:

你需要先导入 copy 模块,然后使用 copy.deepcopy() 函数。
import copy
# 原始字典
original_dict = {
'name': 'Alice',
'scores': [88, 92, 76],
'info': {'city': 'New York'}
}
# 使用 copy.deepcopy() 进行深拷贝
deep_copied_dict = copy.deepcopy(original_dict)
# 修改不可变对象 'name'
deep_copied_dict['name'] = 'Bob'
print(f"Original name: {original_dict['name']}") # 输出: Original name: Alice
print(f"Copied name: {deep_copied_dict['name']}") # 输出: Copied name: Bob
# 不可变对象的修改互不影响,符合预期。
# 修改可变对象 'scores' 中的元素
deep_copied_dict['scores'].append(100)
print("\nAfter modifying 'scores' list:")
print(f"Original scores: {original_dict['scores']}") # 输出: Original scores: [88, 92, 76]
print(f"Copied scores: {deep_copied_dict['scores']}") # 输出: Copied scores: [88, 92, 76, 100]
# 可变对象的修改没有影响原字典!这是深拷贝的核心优势。
# 修改嵌套的可变对象 'info'
deep_copied_dict['info']['city'] = 'Boston'
print("\nAfter modifying nested 'info' dict:")
print(f"Original info: {original_dict['info']}") # 输出: Original info: {'city': 'New York'}
print(f"Copied info: {deep_copied_dict['info']}") # 输出: Copied info: {'city': 'Boston'}
# 嵌套的可变对象的修改也没有影响原字典!
何时使用深拷贝?
深拷贝在你需要完全独立的数据副本时非常有用,尤其是在以下场景:
- 需要修改副本而不影响原始数据:这是最常见的用途,你有一个包含大量配置数据的字典,你想基于这个配置进行一些实验性修改,但又不想破坏原始配置。
- 序列化和反序列化:当你将一个复杂对象(如字典)转换为字符串(如 JSON)时,深拷贝可以确保原始对象不被意外修改。
- 多线程/多进程环境:当多个线程或进程需要访问同一个数据结构,但每个都需要自己的独立副本以避免竞争条件时。
- 缓存机制:当你缓存一个复杂对象时,深拷贝可以确保缓存的对象在后续被修改时,不会影响到原始数据。
性能和内存考量
深拷贝虽然功能强大,但也有一些缺点:
- 性能开销:深拷贝需要递归地遍历整个对象及其内部的所有可变对象,这个过程比浅拷贝要慢得多。
- 内存消耗:深拷贝会创建一个全新的、与原对象一样大的对象树,会消耗更多的内存。
只在确实需要创建完全独立的副本时才使用深拷贝,如果只是需要一个简单的备份,并且你确定只会修改不可变对象,或者不介意修改会同步到原对象,那么浅拷贝(.copy())是更高效的选择。

总结与对比
| 特性 | 浅拷贝 (dict.copy()) |
深拷贝 (copy.deepcopy()) |
|---|---|---|
| 创建方式 | new_dict = old_dict.copy() 或 copy.copy(old_dict) |
import copy; new_dict = copy.deepcopy(old_dict) |
| 顶层字典 | 创建一个新对象 | 创建一个新对象 |
| 不可变元素 | 创建对原元素的引用 | 创建对原元素的引用(因为不可变,效果等同于复制) |
| 可变元素 | 共享引用,修改会影响原对象 | 创建副本,修改不会影响原对象 |
| 嵌套对象 | 共享引用,修改会影响原对象 | 递归创建副本,修改不会影响原对象 |
| 性能 | 快,开销小 | 慢,开销大 |
| 内存 | 省,只复制顶层结构 | 耗,复制整个对象树 |
| 适用场景 | 当你只需要一个字典的独立外壳,且内部可变对象不需要被隔离时。 | 当你需要一个字典的完全独立的副本,任何修改都不能影响原数据时。 |
希望这个详细的解释能帮助你完全理解 Python 字典的 deepcopy!
