TypeError:unhashable type: 'dict'


174

このコードは私にエラーを与えています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)


3
...我々は問題を持っているライン見ることができるようにエラーレポートを表示するために便利になるだろう
drevicko

回答:


248

dictを別のキーdictまたはのキーとして使用しようとしていますset。キーはハッシュ可能でなければならないため、これは機能しません。原則として、不変オブジェクト(文字列、整数、浮動小数点数、フローズンセット、不変タプル)のみがハッシュ可能です(例外は可能です)。したがって、これは機能しません:

>>> 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
おかげで動作しますが、値がdictまたはリスト(ハッシュ不可)の場合はエラーが発生します。今はhash(str(my_dict))を使用していますが、問題なく動作します。
Steven Du

7
単なるメモ@StevenDu辞書は順序を保証しないstr(my_dict)ため、同じ(または異なるが同等の)辞書に対して2つの異なる文字列を返す可能性があります
K Raphael

1
結果のfrozensetをdictに変換するには、を呼び出しますdict(the_frozenset)
ユーザー

4
その私には思えるfrozenset(dict_key.items())2枚の同じ内容のdictsが異なる挿入順序は同じキーにならないことで潜在的に問題です。Sorted()への呼び出しを追加することは適切なようです。たとえばfrozenset(sorted(dict_key.items()))、セットが明示的に順序付けされていないことを考えると、frozensetは奇妙な選択のように見えます。おそらく実際には問題なく動作しますが、タプルは私にとってはより論理的な選択のように思えます。一緒に行きましたtuple(sorted(dict_key.items()))
Jason Heiss

@JasonHeissに同意する
user3732361

6

可能性のある解決策は、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

2
それはそうdumpsであるべきではありませんdump
Kushan Gunasekera
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.