unhashable type: 'dict' Type Error [duplicate]

不打扰是莪最后的温柔 提交于 2019-12-21 06:16:21

问题


Suppose I have this dictionary:

items = {1: {'title': u'testing123', 'description': u'testing456'},
2: {'description': u'testing123', 'description': u'testing456'},
3: {'description': u'testing123', 'description': u'testing456'},
4: {'description': u'testing123', 'description': u'testing456'},
5: {'description': u'testing123', 'description': u'testing456'},
6: {'description': u'somethingelse', 'description': u'somethingelse'}}

I want to filter out the duplicate values, so that in the end I'd get

{1: {'title': u'testing123', 'description': u'testing456'}, 6: {'title': u'something', 'description': u'somethingelse'}}

I wrote this code:

dic = {}

for key, value in items.items():
    if not set(value.values()).issubset(set(dic.values())):
        dic[key] = value

however I get the error message TypeError: unhashable type: 'dict'. I am not sure why this happens and how to fix it.

This is inspired by another question and my failed attempt to solve it.


回答1:


dic.values() return list of dict

>>> for key, value in items.items():
...     print dic.values()
...
[{'description': u'testing456', 'title': u'testing123'}]
[{'description': u'testing456', 'title': u'testing123'}]
[{'description': u'testing456', 'title': u'testing123'}]
[{'description': u'testing456', 'title': u'testing123'}]
[{'description': u'testing456', 'title': u'testing123'}]
[{'description': u'testing456', 'title': u'testing123'}]
>>>

So, you can't apply set on dict as dict is not hashable.

Btw you can fix it by:

>>> dic = {}
>>> for key, value in items.items():
...     if not set(value.values()).issubset(set(sum([x.values() for x in dic.values()],[]))):
...         dic[key] = value
...
>>> dic
{1: {'description': u'testing456', 'title': u'testing123'}, 6: {'description':     u'somethingelse', 'title': u'somethingelse'}}
>>>

For python > 3.x

if not set(value.values()).issubset(set(sum([list(x.values()) for x in list(dic.values())],[]))):



回答2:


Edit: If you must use a set, as others have noted you have to use a hashable object like a tuple:

unique_items = set()
for k, v in items.items():
    sorted_v = tuple(sorted((k2, v2) for k2, v2 in v.items()))
    unique_items.add(sorted_v)
unique_items = dict(unique_items)

gives for unique_items:

{1: {'description': u'testing456', 'title': u'testing123'},
 6: {'description': u'somethingelse', 'title': u'somethingelse'}}

If items is not huge (or, at least if the output dictionary isn't expected to be huge):

items = {1: {'title': u'testing123', 'description': u'testing456'},
2: {'title': u'testing123', 'description': u'testing456'},
3: {'title': u'testing123', 'description': u'testing456'},
4: {'title': u'testing123', 'description': u'testing456'},
5: {'title': u'testing123', 'description': u'testing456'},
6: {'title': u'somethingelse', 'description': u'somethingelse'}}

unique_items = {}
for k, v in items.items():
    if v not in unique_items.values():
        unique_items[k] = v

(assuming the first key in your dictionary example should have been title). But you can't predict what the keys to this dictionary will be if duplicates do exist in items.




回答3:


You are trying to create a set of dicts, but that's not possible, since dicts are unhashable (because they are mutable -- whether they are equal can change as you modify/add/remove pairs in the dict).

Perhaps instead of using the dicts, you can use tuples of their values for your set, a la if not set((v['description_a'], v['description_b]) for v in value.values()).issubset((v['description_a'], v['description_b]) for v in set(dic.values())): or similar?



来源:https://stackoverflow.com/questions/27435798/unhashable-type-dict-type-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!