商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > 合并字典时仅用非 None 值覆盖目标字典中对应键的值

合并字典时仅用非 None 值覆盖目标字典中对应键的值

  发布于2026-07-20 阅读(0)

扫一扫,手机访问

本文介绍如何将一个字典(源)有选择地合并到另一个结构相同但含 none 值的字典(目标)中:仅当源字典中某键的值不为 none 时,才用该值更新目标字典中同名键的值,其余键值对保持不变。

聊一个Python数据处理里很常见的需求:做字典合并的时候,不是一股脑全覆盖,而是有条件地挑着来。比如你手上有个目标字典,里面有些值是None(等待填充的占位符),现在来了一个源字典,你想用它里面实实在在的值去更新目标,但源字典里也带None——那就要跳过这些None,只把非None的拿过来用。听起来简单,但写出来却容易踩坑。

核心诉求其实就一句话:以目标字典的现有结构为基准,只允许源字典中非None的值精准覆盖同名键,不强加新键,也不删已有键,更不把有效数据给覆盖掉。

✅ 推荐实现方式(Python 3.9+)

Python 3.9 引入的字典合并运算符 |= 配合字典推导式,可以说是最优雅的解法:

dict1 = {"a": 0.0, "b": None}
dict2 = {"a": None, "b": 2.2}
# 仅合并 dict1 中 value 不为 None 的键值对
dict2 |= {k: v for k, v in dict1.items() if v is not None}
print(dict2)  # {'a': 0.0, 'b': 2.2}

? 注意:判断条件用 v is not None 而不是 not v,后者会把 0.0、False、[] 这类 falsy 值也过滤掉——但人家明明是有意义的“空值”,不该被跳过。

? 兼容旧版本(Python < 3.9)

版本不够新也没关系,换成 update() 方法,逻辑完全一致:

dict2.update({k: v for k, v in dict1.items() if v is not None})

⚠️ 关键注意事项

  • 要不要引入新键? 上面的写法默认允许源字典里的新键出现在目标字典中。如果想要严格限制——只更新目标字典里已有的键,不新增——那就加个 and k in dict2 条件:
    dict2 |= {k: v for k, v in dict1.items() if v is not None and k in dict2}
  • 源字典保持原样:所有操作都在目标字典上完成,源字典纹丝不动。
  • 只有 None 被跳过:0、空字符串、空列表、False 这些值,只要不是 None,通通视为有效数据,参与合并。
  • 嵌套字典需要递归处理:上面这套方案只适用于扁平字典。如果结构里套着字典,得用递归合并(比如 deepmerge 库,或者自己写个 merge_dict_recursive)。

✅ 验证示例

# 示例 1
dict1 = {"a": 0.0, "b": None}
dict2 = {"a": None, "b": 2.2}
dict2 |= {k: v for k, v in dict1.items() if v is not None}
assert dict2 == {"a": 0.0, "b": 2.2}

# 示例 2
dict1 = {"a": 0.0, "b": 5.5}
dict2 = {"a": None, "b": 2.2}
dict2 |= {k: v for k, v in dict1.items() if v is not None}
assert dict2 == {"a": 0.0, "b": 5.5}

这种方式简洁、高效、语义清晰,处理“优先级覆盖 + None 跳过”这类合并任务,算得上标准的实践写法了。

本文转载于:https://www.php.cn/faq/2325671.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注