TypeError: unhashable type: 'dict'

Эта часть кода дает мне ошибку unhashable type: dict может кто-нибудь объяснить мне, что такое решение

negids = movie_reviews.fileids('neg')
def word_feats(words):
    return dict([(word, True) for word in words])

negfeats = [(word_feats(movie_reviews.words(fileids=[f])), 'neg') for f in negids]
stopset = set(stopwords.words('english'))

def stopword_filtered_word_feats(words):
    return dict([(word, True) for word in words if word not in stopset])

result=stopword_filtered_word_feats(negfeats)

Ответ 1

Вы пытаетесь использовать dict в качестве ключа к другому dict или в set. Это не работает, потому что ключи должны быть хешируемыми. Как правило, только неизменяемые объекты (строки, целые числа, float, frozensets, кортежи неизменяемых) являются хешируемыми (хотя возможны исключения). Так что это не работает:

>>> dict_key = {"a": "b"}
>>> some_dict[dict_key] = True
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'

Чтобы использовать dict в качестве ключа, вам нужно превратить его во что-то, что может быть хэшировано первым. Если dict, который вы хотите использовать как ключ, состоит только из неизменяемых значений, вы можете создать его хешируемое представление следующим образом:

>>> key = frozenset(dict_key.items())

Теперь вы можете использовать key в качестве ключа в dict или set:

>>> some_dict[key] = True
>>> some_dict
{frozenset([('a', 'b')]): True}

Конечно, вам нужно повторять упражнение всякий раз, когда вы хотите что-то искать с помощью dict:

>>> some_dict[dict_key]                     # Doesn't work
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>> some_dict[frozenset(dict_key.items())]  # Works
True

Если dict, который вы хотите использовать как ключ, имеет значения, которые сами являются dicts и/или списками, вам необходимо рекурсивно "заморозить" предполагаемый ключ. Здесь начальная точка:

def freeze(d):
    if isinstance(d, dict):
        return frozenset((key, freeze(value)) for key, value in d.items())
    elif isinstance(d, list):
        return tuple(freeze(value) for value in d)
    return d

Ответ 2

Возможным решением может быть использование метода JSON dumps(), чтобы вы могли преобразовать словарь в строку -

import json
a={"a":10, "b":20}
b={"b":20, "a":10}
c = [json.dumps(a), json.dump(b)]
set(c)
json.dump(a) in c

Вывод -

set(['{"a": 10, "b": 20}'])
True