【AI总结】别再用 = 了!Python 复制字典的 6 种姿势,你 pick 谁?

别再用 = 了!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语法糖,与上接近
推导式200Python 层循环
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 + 类型判断。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荔枝吻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值