如何检索字典中具有重复列表值的对应键?
解决字典中重复列表值的键检索问题
问题核心
直接用collections.Counter统计字典的列表值会触发TypeError: unhashable type: 'list',原因是列表是可变、不可哈希的类型,而Counter的统计对象必须是可哈希的(比如字符串、元组、数字等),所以直接用这个方法行不通,但可以通过转换值的类型来适配,同时还有更高效的实现方案。
方案一:用defaultdict映射元组到键列表(推荐)
把列表转成不可变的元组(可哈希),然后用defaultdict记录每个元组对应的所有键,最后筛选出对应多个键的元组即可:
from collections import defaultdict d1 = {'a': ['abc','cde','abc'], 'b': ['a', 'd', 'f'], 'c': ['abc','cde','abc']} # 构建元组到对应键的映射 tuple_key_map = defaultdict(list) for key, val in d1.items(): tuple_val = tuple(val) tuple_key_map[tuple_val].append(key) # 获取所有重复列表对应的键(扁平化结果) duplicate_keys = sum([keys for keys in tuple_key_map.values() if len(keys) > 1], []) print(duplicate_keys) # 输出: ['a', 'c'] # 如果需要{'a':'c'}这种键值对形式(假设每组重复仅两个键) duplicate_pairs = {} for keys in tuple_key_map.values(): if len(keys) >= 2: duplicate_pairs[keys[0]] = keys[1] print(duplicate_pairs) # 输出: {'a': 'c'}
这个方案只需要遍历字典一次,时间复杂度为O(n),效率更高。
方案二:转换类型后用Counter统计
先把所有列表值转成元组,用Counter统计元组的出现次数,再反向找出对应次数大于1的元组的所有键:
from collections import Counter d1 = {'a': ['abc','cde','abc'], 'b': ['a', 'd', 'f'], 'c': ['abc','cde','abc']} # 把列表转成元组,生成统计列表 tuple_values = [tuple(val) for val in d1.values()] val_counter = Counter(tuple_values) # 筛选出出现次数>1的元组 duplicate_tuples = [t for t, count in val_counter.items() if count > 1] # 收集对应键 duplicate_keys = [] for t in duplicate_tuples: for key, val in d1.items(): if tuple(val) == t: duplicate_keys.append(key) print(duplicate_keys) # 输出: ['a', 'c']
这个方案逻辑直观,但需要多次遍历,效率略低于第一种方案。
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

