如何合并Python字典中值相同的键为元组,生成新字典?
问题:合并字典中值相同的键
给定如下Python字典:
test_dict = { 'a': [1,3,5], 'b': [9,3,4], 'c': [4,5,6], 'd': [1,3,6], 'e': [1,3,5], 'f': [1,3,5], 'g': [4,5,6], 'h': [6,5,9] }
需要将所有值相同的键合并为元组,作为新字典的键,对应唯一的共同值,期望结果如下:
result = { ('a','e','f'): [1,3,5], 'b': [9,3,4], ('c','g'): [4,5,6], 'd': [1,3,6], 'h': [6,5,9] }
目前仅实现了按指定值查找对应键的功能,代码如下:
test_dict = { 'a': [1,3,5], 'b': [9,3,4], 'c': [4,5,6], 'd': [1,3,6], 'e': [1,3,5], 'f': [1,3,5], 'g': [4,5,7], 'h': [6,5,9] } list_to_find = [1,3,5] def found_duplicates(target_dict, value_to_find): found_keys = [] for k in test_dict.keys(): value_for_k = test_dict[k] if(value_for_k == list_to_find): found_keys.append(k) return tuple(found_keys) print(found_duplicates(test_dict, list_to_find))
更优实现方法
核心思路是反向构建映射:先把原字典的值(转成不可变类型)作为键,收集所有对应这个值的原键,再根据收集到的键的数量生成最终字典。这种方法只需遍历原字典两次,时间复杂度为O(n),效率远高于逐个值查找的方式。
方法1:使用collections.defaultdict简化代码
from collections import defaultdict test_dict = { 'a': [1,3,5], 'b': [9,3,4], 'c': [4,5,6], 'd': [1,3,6], 'e': [1,3,5], 'f': [1,3,5], 'g': [4,5,6], 'h': [6,5,9] } # 第一步:构建值到对应键列表的映射 value_to_keys = defaultdict(list) for key, val in test_dict.items(): # 列表是可变类型不能作为字典键,转成元组 value_to_keys[tuple(val)].append(key) # 第二步:生成结果字典 result = {} for val_tuple, keys in value_to_keys.items(): original_val = list(val_tuple) if len(keys) > 1: result[tuple(keys)] = original_val else: result[keys[0]] = original_val print(result)
方法2:不依赖额外库,用普通字典实现
如果不想导入collections模块,可以用普通字典手动处理:
test_dict = { 'a': [1,3,5], 'b': [9,3,4], 'c': [4,5,6], 'd': [1,3,6], 'e': [1,3,5], 'f': [1,3,5], 'g': [4,5,6], 'h': [6,5,9] } value_to_keys = {} for key, val in test_dict.items(): val_tuple = tuple(val) if val_tuple not in value_to_keys: value_to_keys[val_tuple] = [] value_to_keys[val_tuple].append(key) result = {} for val_tuple, keys in value_to_keys.items(): original_val = list(val_tuple) result[tuple(keys) if len(keys) > 1 else keys[0]] = original_val print(result)
代码逻辑说明
- 转换值的类型:因为列表是可变类型,无法作为字典的键,所以先将原字典的值转换为元组(不可变、可哈希)作为临时映射的键。
- 收集对应键:遍历原字典,把每个键添加到对应值的键列表中,完成“值→键列表”的反向映射。
- 生成最终字典:遍历临时映射,根据键列表的长度决定新字典的键形式——长度大于1时用元组,否则直接用单个键,对应的值还原为原来的列表。
内容的提问来源于stack exchange,提问作者Xagih
相关产品推荐
相关产品推荐

