why dict objects are unhashable in python?

Question:

I mean why cant we put key of dict as dict?

that means we can’t have dictionary having key as another dictionary…

Asked By: shahjapan

||

Answers:

Short answer: because they are mutable containers.

If a dict was hashed, its hash would change as you changed its contents.

Answered By: Ben James

None of the mutable container types in Python are hashable, because they are mutable and thus their hash value can change over their lifetime.

Answered By: user3850

As others have said, the hash value of a dict changes as the contents change.

However if you really need to use dicts as keys, you can subclass dict to make a hashable version.

>>> class hashabledict(dict):
...    def __hash__(self):
...        return id(self)
... 
>>> hd = hashabledict()
>>> d = dict()
>>> d[hd] = "foo"
>>> d
{{}: 'foo'}

>>> hd["hello"] = "world"
>>> d
{{'hello': 'world'}: 'foo'}

This replaces the hash value used for the dict with the object’s address in memory.

Answered By: Dave Kirby

This is easy to deal with. Wrap a dict in a frozenset before you hash it. Then, when you need to use it, convert it back to a dict.

>>> unhashable = {'b': 'a', 'a': 'b'}
>>> hashable = frozenset(unhashable.items())
>>> unhashable = dict(hashable)
>>> unhashable
{'a': 'b', 'b': 'a'}

Note that dictionary key order is undefined anyway, so the change in key order doesn’t matter.

Answered By: user240515

For maybe the wrong reasons I’ve ran into this problem a bunch of times; where I want to reference a full dict as a key to something. I don’t need it to be mutable, but I do want to preserve and easily access the dict‘s members.

The easiest way I’ve found to make the dict immutable and quickly usable as a key value is to make it a JSON (or serialize in your favorite alternative).

For example:

>>> import json
>>> d = {'hey':1, 'there':2}
>>> d_key = json.dumps(d)
>>> d_key
'{"there": 2, "hey": 1}'
>>> d2 = {d_key: 'crazytown'}
>>> d2
{'{"there": 2, "hey": 1}': 'crazytown'}

It’s easy to manipulate, since it’s just a string. And, it can be de-serialized into an object if you want to reference its members.

Answered By: Bill Gross
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.