递归合并字典:同层级共享键值合并为列表的实现需求
递归合并嵌套字典(保留重复键的所有值)
这个需求确实很常见——普通的a.update(b)只会粗暴覆盖重复键的值,完全没法满足你要保留所有信息的要求。我们需要写一个递归处理嵌套层级的合并函数,来实现相同键的值合并为列表、嵌套字典继续递归合并的逻辑。
实现代码
def merge_dicts(a, b): # 先复制字典a的内容作为合并的基础,避免修改原字典 merged = dict(a) for key, value in b.items(): if key in merged: # 如果两边都是嵌套字典,递归处理内层合并 if isinstance(merged[key], dict) and isinstance(value, dict): merged[key] = merge_dicts(merged[key], value) else: # 将现有值转为列表(如果还不是列表的话) if not isinstance(merged[key], list): merged[key] = [merged[key]] # 处理b中的值:如果是列表就扩展,否则直接追加 if isinstance(value, list): merged[key].extend(value) else: merged[key].append(value) else: # 键不存在于a中,直接添加到合并结果里 merged[key] = value return merged
测试验证
用你的示例字典来测试:
a = {"name": "john", "phone":"123123123", "owns": {"cars": "Car 1", "motorbikes": "Motorbike 1"}} b = {"name": "john", "phone":"123", "owns": {"cars": "Car 2"}} merged_result = merge_dicts(a, b) print(merged_result)
输出结果完全符合你的期望:
{"name": "john", "phone":["123123123","123"], "owns": {"cars": ["Car 1", "Car 2"], "motorbikes": "Motorbike 1"}}
逻辑说明
- 首先复制原字典
a的内容,避免修改原始数据 - 遍历字典
b的每一个键值对:- 如果键已经存在于合并结果中:
- 若两边的值都是字典,递归调用函数处理内层嵌套的合并
- 若不是字典,先把合并结果中已有的值转为列表(确保格式统一),再把
b中的值添加进去(兼容b的值本身就是列表的情况)
- 如果键不存在,直接将
b的键值对加入合并结果
- 如果键已经存在于合并结果中:
对比a.update(b)的输出:
{'name': 'john', 'phone': '123', 'owns': {'cars': 'Car 2'}}
可以看到我们的递归函数完美保留了所有层级的重复键信息,没有任何数据丢失。
内容的提问来源于stack exchange,提问作者Depa
相关产品推荐
相关产品推荐

