This piece of code is giving me an error unhashable type: dict can anyone explain to me what the solution is?
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) 23 Answers
You're trying to use a dict as a key to another dict or in a set. That does not work because the keys have to be hashable. As a general rule, only immutable objects (strings, integers, floats, frozensets, tuples of immutables) are hashable (though exceptions are possible). So this does not work:
>>> dict_key = {"a": "b"} >>> some_dict[dict_key] = True Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'dict' To use a dict as a key you need to turn it into something that may be hashed first. If the dict you wish to use as key consists of only immutable values, you can create a hashable representation of it like this:
>>> key = frozenset(dict_key.items()) Now you may use key as a key in a dict or set:
>>> some_dict[key] = True >>> some_dict {frozenset([('a', 'b')]): True} Of course you need to repeat the exercise whenever you want to look up something using a 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 If the dict you wish to use as key has values that are themselves dicts and/or lists, you need to recursively "freeze" the prospective key. Here's a starting point:
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 10A possible solution might be to use the JSON dumps() method, so you can convert the dictionary to a string ---
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 Output -
set(['{"a": 10, "b": 20}']) True 2def frozendict(d: dict): return frozenset(d.keys()), frozenset(d.values()) 2