354 Stimmen

TypeError: unhashbarer Typ: 'dict'

Dieser Teil des Codes gibt eine Fehlermeldung aus unhashable type: dict Kann mir jemand erklären, was die Lösung ist?

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)

457voto

Lauritz V. Thaulow Punkte 45363

Sie versuchen, eine dict als Schlüssel zu einem anderen dict oder in einer set . Das funktioniert nicht, weil die Schlüssel hashfähig sein müssen. In der Regel sind nur unveränderliche Objekte (Strings, Integers, Floats, Frozensets, Tupel von unveränderlichen Objekten) hashfähig (Ausnahmen sind jedoch möglich). Dies funktioniert also nicht:

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

Um ein Diktat als Schlüssel zu verwenden, müssen Sie es zuerst in etwas verwandeln, das gehasht werden kann. Wenn das Diktat, das Sie als Schlüssel verwenden möchten, nur aus unveränderlichen Werten besteht, können Sie eine Hash-Darstellung davon wie folgt erstellen:

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

Jetzt können Sie key als Schlüssel in einer dict o set :

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

Natürlich müssen Sie die Übung jedes Mal wiederholen, wenn Sie etwas mit einem Diktat nachschlagen wollen:

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

Si le dict die Sie als Schlüssel verwenden möchten, Werte hat, die selbst Dicts und/oder Listen sind, müssen Sie den zukünftigen Schlüssel rekursiv "einfrieren". Hier ist ein Ansatzpunkt:

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

39voto

Matteo Boscolo Punkte 509

Eine mögliche Lösung wäre die Verwendung der JSON dumps()-Methode, mit der Sie das Wörterbuch in eine Zeichenkette umwandeln können ---

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

Ausgang -

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

6voto

Nathan Clement Punkte 1063

Das ist mir passiert, weil ich in Typescript gedacht habe und versucht habe, ein Python-Wörterbuch wie folgt einzurichten:

thing = { 'key': 'value' }
other_thing = {'other_key': 'other_value'}
my_dictionary = { thing, other_thing }

Dann habe ich es versucht:

my_dictionary = { thing: thing, other_thing: other_thing }

...was immer noch nicht funktioniert hat

Was letztendlich funktionierte, war...

my_dictionary = { 'thing': thing, 'other_thing': other_thing }

Komisch, wie sehr wir uns an die kleinen Syntaxtricks der verschiedenen Sprachen gewöhnt haben...

-1voto

Wotchin Punkte 96
def frozendict(d: dict):
    keys = sorted(d.keys())
    return tuple((k, d[k]) for k in keys)

Die Implementierung der obigen Funktion gibt eine unveränderliche Struktur zurück, und wir ziehen es vor, den Schlüssel zu sortieren, um ungeordnete Iterationen zu vermeiden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X