推荐用 | 运算符(Python 3.9+)合并字典,简洁、可读性强、性能优、不修改原字典;兼容旧版可用 {d1, d2};仅需原地修改时才用 update()。

直接用 |(Python 3.9+)或 {**d1, **d2}(3.5+),别再写 d1.copy().update(d2) —— 多余、慢、易错。
用 | 运算符(推荐,3.9+)
这是目前最简洁、可读性最强、且性能略优的方式。它明确表达“合并两个字典并返回新对象”的意图,底层由 C 实现,避免中间对象开销。
-
|创建新字典,不修改任一原字典 - 键冲突时,右侧字典的值覆盖左侧
- 支持链式:比如
defaults | user_cfg | overrides - 注意:
dict1 | list1会抛TypeError,类型检查比**更严格
示例:merged = {'a': 1} | {'b': 2, 'a': 99} → {'a': 99, 'b': 2}
用 {**d1, **d2} 解包(兼容 3.5+)
仍是主流选择,尤其当项目还没升级到 3.9。语义清晰,但本质是语法糖,实际会构造临时映射并逐项插入。
立即学习“Python免费学习笔记(深入)”;
- 行为与
|完全一致:新建字典、右键覆盖 - 在 Python 3.8 及更早版本中,
**解包比copy()+update()快约 10–15% - 容易误写成
{*d1, *d2}(报TypeError: unhashable type: 'dict') - 若字典含不可哈希键(如列表),错误发生在运行时,而
|在类型检查阶段就可能暴露问题
用 dict1.update(dict2)(仅需原地修改时)
唯一真正“高效”于内存和速度的原地操作,但代价是破坏原字典引用——这点常被忽略。
- 不创建新字典,也不复制键值对,直接复用
dict1的底层哈希表空间 - 性能实测仍略快于
|(微秒级差异),但仅在你确定不需要dict1原始状态时才值得用 - 常见陷阱:函数参数传入字典后直接
.update(),导致调用方看到意外修改 - 若需保留原字典又想原地更新,必须显式
target = d1.copy(); target.update(d2),此时已不如|简洁
别踩这些坑
很多“看似能跑”的写法其实埋着雷:
- 写
dict1.update(dict2).update(dict3)——update()返回None,第二步直接报错 - 用
ChainMap(d1, d2)当作合并结果 —— 它不是字典,没有.keys()等方法,且查键只取第一个匹配,不是真合并 - 在循环里反复
merged = {**merged, **new}—— 每次都新建字典,时间复杂度 O(n²),大数据量下明显卡顿 - 假设
|支持嵌套合并 —— 它只做浅层合并;嵌套结构需用deepmerge或手动递归
真正要注意的不是“怎么写”,而是“要不要新对象”和“Python 版本是否允许”。一旦明确这两点,剩下只是选 | 还是 {**} 的事——其余方式,多数时候只是给自己加维护成本。


















