如何在Python中合并字典并完整保留数据,支持列表值合并?
问题
在Python中合并两个字典时,希望键重叠时将对应值合并为列表,同时兼容值本身就是列表的场景。现有代码仅能处理值为非列表的情况,无法满足更通用的需求:
现有代码:
dict1 = {'a': 1, 'b': 2, 'c': 3} dict2 = {'b': 3, 'c': 4, 'd': 5} merged_dict = dict1.copy() for key, value in dict2.items(): if key in merged_dict: merged_dict[key] = [merged_dict[key], value] else: merged_dict[key] = value print(merged_dict)
输出结果:
{'a': 1, 'b': [2, 3], 'c': [3, 4], 'd': 5}
当遇到值本身为列表的字典时,现有方法处理结果不符合预期:
待合并字典:
dict1 = {'a': [1], 'b': 2} dict2 = {'a': 3, 'b': [4], 'c': 5}
期望输出:
{'a': [1, 3], 'b': [2, 4], 'c': 5}
解决方案
1. 通用处理函数
通过判断值的类型,统一将单个元素和列表进行合并,最后可选择将单元素列表还原为单个值:
def merge_dicts(dict1, dict2): merged = {} # 初始化第一个字典的键值对,统一包装为列表 for key, val in dict1.items(): merged[key] = val if isinstance(val, list) else [val] # 遍历第二个字典,合并对应键的值 for key, val in dict2.items(): if key in merged: if isinstance(val, list): merged[key].extend(val) else: merged[key].append(val) else: merged[key] = val if isinstance(val, list) else [val] # 还原单元素列表为单个值(不需要可删除此步骤) for key in merged: if len(merged[key]) == 1: merged[key] = merged[key][0] return merged # 测试案例1 dict1 = {'a': 1, 'b': 2, 'c': 3} dict2 = {'b': 3, 'c': 4, 'd': 5} print(merge_dicts(dict1, dict2)) # 输出: {'a': 1, 'b': [2, 3], 'c': [3, 4], 'd': 5} # 测试案例2 dict1 = {'a': [1], 'b': 2} dict2 = {'a': 3, 'b': [4], 'c': 5} print(merge_dicts(dict1, dict2)) # 输出: {'a': [1, 3], 'b': [2, 4], 'c': 5}
2. 更Pythonic的实现:使用collections.defaultdict
借助defaultdict简化键的初始化逻辑,代码更简洁:
from collections import defaultdict def merge_dicts(dict1, dict2): merged = defaultdict(list) # 遍历两个字典,统一将值添加到对应键的列表中 for d in [dict1, dict2]: for key, val in d.items(): if isinstance(val, list): merged[key].extend(val) else: merged[key].append(val) # 转换为普通字典并处理单元素列表 return {k: v[0] if len(v) == 1 else v for k, v in merged.items()} # 测试案例 dict1 = {'a': [1], 'b': 2} dict2 = {'a': 3, 'b': [4], 'c': 5} print(merge_dicts(dict1, dict2)) # 输出: {'a': [1, 3], 'b': [2, 4], 'c': 5}
3. 扩展:合并多个字典
如果需要合并两个以上的字典,可借助itertools.chain批量处理:
from collections import defaultdict from itertools import chain def merge_multiple_dicts(*dicts): merged = defaultdict(list) # 遍历所有字典的键值对 for key, val in chain.from_iterable(d.items() for d in dicts): if isinstance(val, list): merged[key].extend(val) else: merged[key].append(val) # 转换为普通字典并处理单元素列表 return {k: v[0] if len(v) == 1 else v for k, v in merged.items()} # 测试 dict1 = {'a': [1], 'b': 2} dict2 = {'a': 3, 'b': [4]} dict3 = {'a': [5,6], 'c': 7} print(merge_multiple_dicts(dict1, dict2, dict3)) # 输出: {'a': [1, 3, 5, 6], 'b': [2, 4], 'c': 7}
内容的提问来源于stack exchange,提问作者Ritesh Singh
相关产品推荐
相关产品推荐

