279

这段代码给了我一个错误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)
4

2 回答 2

367

您正在尝试将 adict用作另一个dictset. 这不起作用,因为密钥必须是可散列的。作为一般规则,只有不可变对象(字符串、整数、浮点数、冻结集、不可变元组)是可散列的(尽管可能有例外)。所以这不起作用:

>>> 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())

现在您可以在 a或key中用作键:dictset

>>> 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您希望用作键的值本身就是字典和/或列表,则需要递归地“冻结”预期键。这是一个起点:

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
于 2012-11-07T07:03:52.613 回答
26

一个可能的解决方案可能是使用 JSON dumps() 方法,因此您可以将字典转换为字符串 ---

import json

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


set(c)
json.dumps(a) in c

输出 -

set(['{"a": 10, "b": 20}'])
True
于 2019-09-07T09:03:10.763 回答