嵌套字典去重时遭遇'unhashable type: dict'错误求助
问题:嵌套字典去重时触发
unhashable type: 'dict'错误 我有一个名为solutions的字典,每个键对应一个嵌套字典作为值,内层字典包含运输详情,需要保留生成顺序。字典部分示例如下:
{'Eval-49998': {'N1': {('N2', 'RD', 'C7'): [27.33, 0.5, 0.75, 78.1]}, 'N2': {('N3', 'AR', 'C5'): [63, 0.5, 11.1, 158.25]}, 'N3': {('N4', 'RD', 'C7'): [15.0, 0.5, 0.33, 42.9]}, 'Cost': 159.31, 'Distance': 642.33, 'Time': 12.18, 'Total Rewards': -151.38}, 'Eval-49999': {'N1': {('N2', 'RD', 'C7'): [27.33, 0.5, 0.75, 78.1]}, 'N2': {('N3', 'AR', 'C5'): [63, 0.5, 11.1, 158.25]}, 'N3': {('N4', 'RD', 'C7'): [15.0, 0.5, 0.33, 42.9]}, 'Cost': 159.31, 'Distance': 642.33, 'Time': 12.18, 'Total Rewards': -151.38}}
可以看到,Eval-49998和Eval-49999对应的内层字典完全相同。这个字典共有50000个条目,存在大量重复项,我需要去除重复条目,仅保留每个唯一条目首次出现的键值对。
之后我调用去重方法、排序并打印:
solutions = dedupeSolutions(solutions) sorted_rewards = sorted(solutions.keys(), key=lambda x: solutions[x]['Total Rewards']) for i in sorted_rewards: print(i, ": ", solutions[i])
dedupeSolutions函数定义如下:
def dedupeSolutions(the_solution): u = set() dedupedSolutions = dict() for k in the_solution.items(): print(k) if k[1] not in u: u.add(k[1]) dedupedSolutions[k[0]] = k[1] return dedupedSolutions
执行时触发错误:
Traceback (most recent call last): File "/Users/tapas/PycharmProjects/Q-Learn/routing.py", line 330, in <module> solutions = dedupeSolutions(solutions) File "/Users/tapas/PycharmProjects/Q-Learn/routing.py", line 205, in dedupeSolutions if k[1] not in u: TypeError: unhashable type: 'dict'
错误原因
Python中集合(set)的元素必须是**可哈希(hashable)**类型,而字典(dict)是可变类型,无法被哈希,所以直接把内层字典加入集合会触发TypeError。
解决方案
要判断嵌套字典是否重复,需要把可变的字典转换成可哈希的类型,比如将字典序列化为字符串,或者转换成不可变的元组结构,再存入集合做去重判断。
方案1:使用JSON序列化(推荐,结构清晰)
利用json.dumps把嵌套字典转换成字符串,指定sort_keys=True,确保相同结构的字典序列化后得到相同的字符串(因为字典的键顺序不影响内容,但序列化时顺序不同会导致字符串不同)。
修改后的dedupeSolutions函数:
import json def dedupeSolutions(the_solution): seen = set() deduped = {} for key, value in the_solution.items(): # 把嵌套字典序列化为排序后的JSON字符串,确保相同内容得到相同字符串 serialized = json.dumps(value, sort_keys=True) if serialized not in seen: seen.add(serialized) deduped[key] = value return deduped
方案2:转换为不可变元组
把嵌套字典的键值对递归转换成不可变的元组结构(元组是可哈希类型),适合不想引入JSON依赖的场景。
递归转换函数示例:
def dict_to_tuple(d): if isinstance(d, dict): return tuple(sorted((k, dict_to_tuple(v)) for k, v in d.items())) elif isinstance(d, list): return tuple(dict_to_tuple(item) for item in d) else: return d def dedupeSolutions(the_solution): seen = set() deduped = {} for key, value in the_solution.items(): # 把嵌套字典转换成不可变元组 hashable_value = dict_to_tuple(value) if hashable_value not in seen: seen.add(hashable_value) deduped[key] = value return deduped
内容的提问来源于stack exchange,提问作者user1931485
相关产品推荐
相关产品推荐

