2012-11-07 12 views
82

questo pezzo di codice mi sta dando un errore unhashable type: dict qualcuno mi può spiegare che cosa è la soluzioneTypeError: Tipo di calcolo dell'hash: '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) 
+2

RST http://docs.python.org/2.7/library/stdtypes.html#mapping-types-dict – iMom0

+0

Sarebbe utile per mostrare il rapporto di errore in modo che possiamo vedere quale linea ha il problema ... – drevicko

risposta

139

Si sta tentando di usare un dict come chiave per un'altra dict o in un set. Questo non funziona perché le chiavi devono essere lavabili. Come regola generale, solo gli oggetti immutabili (stringhe, interi, float, frozenset, tuple di immutables) sono lavabili (anche se sono possibili eccezioni). Quindi questo non funziona:

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

Per utilizzare un dict come una chiave è necessario trasformarlo in qualcosa che può essere hash prima. Se il dict si desidera utilizzare come chiave è costituito da soli valori immutabili, è possibile creare una rappresentazione hashable a come questo:

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

Ora è possibile utilizzare key come una chiave in una dict o set:

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

Naturalmente è necessario ripetere l'esercizio ogni volta che si desidera cercare qualcosa usando un 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 

Se il 012.che si desidera utilizzare come chiave ha valori che sono a loro volta dicts e/o liste, è necessario ricorsivamente "congelare" la chiave futura. Ecco un punto di partenza:

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

Grazie, funziona, tuttavia ottieni ancora un errore se il valore è un dict o lista (inammissibile), ora sto usando hash (str (my_dict)), funziona bene per me. –

+2

solo una nota I dizionari @StevenDu non garantiscono l'ordine, quindi 'str (my_dict)' potrebbe restituire due diverse stringhe per le stesse (o diverse, ma equivalenti) dicts –

Problemi correlati