Python递归合并多层嵌套字典 保留原值补全缺失键默认值
嵌套字典默认值补全实现
合并规则
- 原始字典(Original)优先级最高,所有已有键值完整保留,不做任何覆盖
- 仅补充模板字典(Example)中存在、原始字典缺失的键及对应默认值
- 支持字典、列表混合的任意多层嵌套结构
原有代码问题说明
之前写的两个函数无法得到正确结果,核心问题如下:
update2存在的问题:- 缩进错误,函数调用语句写在了函数体内部
- 没有处理列表类型的嵌套逻辑,遇到列表结构直接跳过合并
- 递归调用写法错误,Python字典没有内置
update2方法 - 函数没有设置返回值,执行后默认返回
None
update3存在的问题:- 强行把所有值包裹成列表,完全破坏原有数据结构
- 没有递归处理嵌套的字典、列表结构
- 优先级逻辑写反,会覆盖原始字典的已有值
- 同样没有返回值,打印结果只能得到
None
可直接落地的实现代码
def merge_default(original: dict, template: dict) -> dict: # 拷贝原始字典,避免修改传入的原数据 res = original.copy() for key, t_val in template.items(): # 键不存在时直接补模板默认值 if key not in res: res[key] = t_val continue o_val = res[key] # 两边值都是字典,递归合并 if isinstance(o_val, dict) and isinstance(t_val, dict): res[key] = merge_default(o_val, t_val) # 两边值都是列表,按索引逐元素合并 elif isinstance(o_val, list) and isinstance(t_val, list): merged_list = [] max_idx = max(len(o_val), len(t_val)) for i in range(max_idx): # 原始列表无当前索引元素,直接用模板值 if i >= len(o_val): merged_list.append(t_val[i]) # 模板无当前索引元素,保留原始值 elif i >= len(t_val): merged_list.append(o_val[i]) # 同索引位置都是字典,递归合并 elif isinstance(o_val[i], dict) and isinstance(t_val[i], dict): merged_list.append(merge_default(o_val[i], t_val[i])) # 其他类型值直接保留原始内容 else: merged_list.append(o_val[i]) res[key] = merged_list return res # 测试样例(修正了原代码中缺失冒号的语法错误) if __name__ == "__main__": Original = {"key1": {"key2":[{"key3": "y1" , "key5": "z1" , "key6": [{"key7": "n1"}]}]}} Example = {"key1": {"key2":[{"key3": None , "key4": None ,"key5": None , "key6": [{"key7": None,"key8":None}]}]}} final_json = merge_default(Original, Example) print(final_json)
运行效果
执行代码后输出结果和预期完全一致:
{'key1': {'key2': [{'key3': 'y1', 'key5': 'z1', 'key6': [{'key7': 'n1', 'key8': None}], 'key4': None}]}}
使用注意
- 调用时第一个参数传实际业务数据字典,第二个参数传读取出的模板默认值字典即可
- 函数不会修改传入的原始字典,无需担心原数据被改动
- 只要实际数据和模板的层级结构对应,任意深度的嵌套都可以自动补全缺失键
内容的提问来源于stack exchange,提问作者learner
相关产品推荐
相关产品推荐

