Python 3.9 的 | 运算符用于字典浅层合并,返回新字典、支持链式操作且右操作数优先覆盖同名键;不递归合并嵌套结构,仅整体替换值,非 Python 3.9+ 不可用。

Python 3.9 的 | 运算符能直接合并字典,但只做浅层覆盖,不递归合并嵌套结构。
为什么用 | 而不是 update() 或 ** 解包
因为 | 返回新字典,不修改原字典,语义清晰且支持链式操作;update() 是就地修改,** 在多个字典时写法冗长(如 {**d1, **d2, **d3}),而 d1 | d2 | d3 更直观。它也是唯一原生支持“右操作数优先覆盖左操作数同名键”的内置运算符。
-
d1 | d2中,若键重复,d2的值生效 - 不支持
|=对不可变字典(如frozendict)赋值,仅适用于dict - 左操作数必须是
dict,右操作数可以是任意映射类型(如dict、MappingProxyType),但需实现keys()和__getitem__()
| 合并时遇到嵌套字典会怎样
它完全不处理嵌套:遇到同名键,直接用右边整个值替换左边值,不会深入合并子字典。比如 d1 = {"a": {"x": 1}} 和 d2 = {"a": {"y": 2}},d1 | d2 结果是 {"a": {"y": 2}},不是 {"a": {"x": 1, "y": 2}}。
librosa 是一个用于音频和音乐分析的 Python 库。它提供了特征提取、频谱分析、节拍跟踪、起始检测和音频可视化的工具,基于 NumPy 和 SciPy 构建,用于科学音频计算。
- 需要递归合并,请改用第三方库(如
deepmerge)或手写递归函数 - 如果只是想保留左边嵌套结构、仅覆盖右边的顶层键,
|完全够用 - 误以为
|会深合并,是初学者最常踩的坑
实际使用中的兼容性与限制
| 是 Python 3.9+ 独占特性,在 3.8 及更早版本中会触发 SyntaxError: invalid syntax。CI 或多版本环境中需留意。
- 不能用于
collections.ChainMap或types.MappingProxyType作为左操作数(会报TypeError: unsupported operand type(s)) - 性能上,
|比{**d1, **d2}略快(C 实现),但差距在微秒级,一般无需优化 - 若需合并后校验键类型(如确保所有键都是字符串),得额外写逻辑 ——
|不做任何类型检查
真正要注意的是:它看起来像“智能合并”,其实只是键值对的线性覆盖。嵌套、列表、自定义对象等复杂结构,都得靠你自己兜底处理。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










