文章目录
别再用 = 了!Python 复制字典的 6 种姿势,你 pick 谁?
在 Python 里,字典(dict)是最灵活的数据结构之一。但当你想“整一份一模一样的”字典时,却发现 new_dict = old_dict 根本不管用!今天就带你从浅拷贝到深拷贝,从语法糖到黑科技,一口气梳理 6 种常用复制姿势,附带性能对比与踩坑预警,建议收藏!
1. 直接赋值:只是贴了个“标签”
old = {'a': 1, 'b': [2, 3]}
new = old # 这不是复制!
new['a'] = 999
print(old) # {'a': 999, 'b': [2, 3]} 原字典被改了!
🚩 结论:赋值只是增加了一个引用,新旧变量指向同一块内存。
适用场景:读操作 或明确希望共享数据时。
2. 浅拷贝:复制“外壳”,不复制“内脏”
2.1 内置方法 copy()
new = old.copy()
2.2 工厂函数 dict()
new = dict(old)
2.3 字典解包 {**old}(Python 3.5+)
new = {**old}
2.4 推导式(可读性高)
new = {k: v for k, v in old.items()}
🚩 结论:以上 4 种都属于 浅拷贝(shallow copy)。
当字典的 value 是可变对象(如列表、嵌套字典)时,内层对象仍共享引用:
old['b'].append(4)
print(new) # {'a': 1, 'b': [2, 3, 4]} 内层被同步修改!
3. 深拷贝:连“内脏”一起复制
import copy
new = copy.deepcopy(old)
🚩 结论:递归复制所有层级,彻底隔离。
代价:速度慢、内存占用高。
适用场景:字典嵌套层级深,或 value 包含自定义对象。
4. 性能大 PK
在 CPython 3.11 + macOS 实测(字典大小 1e5 个键值对):
| 方法 | 耗时 (μs) | 备注 |
|---|---|---|
dict.copy() | 125 | 最快,内置 C 实现 |
dict(old) | 180 | 稍慢,多一次构造 |
{**old} | 190 | 语法糖,与上接近 |
| 推导式 | 200 | Python 层循环 |
copy.deepcopy() | 12,000+ | 深拷贝,慢一个数量级 |
结论:浅拷贝首选
dict.copy(),深拷贝别无选择deepcopy。
5. 总结:一张图告诉你该怎么选
graph TD
A[需要复制字典?] -->|value 全为不可变| B[浅拷贝即可]
A -->|value 含可变对象| C[需要深拷贝?]
B --> D[推荐 dict.copy() 或 {**dict}]
C -->|是| E[copy.deepcopy]
C -->|否| F[浅拷贝]
6. 彩蛋:为什么 copy() 比 dict() 快?
dict.copy() 直接调用 C 层的 _PyDict_Copy,零 Python 字节码;
而 dict(old) 会走通用构造流程,多一次类型检查与哈希表预分配。
7. 评论区高频问答
-
Q:深拷贝后,key 的顺序会变吗?
A:Python 3.7+ 字典有序,deepcopy会保持顺序。 -
Q:如何只深拷贝 value 为字典的项?
A:自定义递归函数或用collections.defaultdict+ 类型判断。

被折叠的 条评论
为什么被折叠?



