shahjapan
shahjapan

Reputation: 14335

why dict objects are unhashable in python?

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

that means we can't have dictionary having key as another dictionary...

Upvotes: 32

Views: 35856

Answers (6)

alexkim
alexkim

Reputation: 36

You can use id(inner_dict) as the key to the outer dictionary.

This gives the same behavior as Java where the default hashcode of an Object is guaranteed to be unique for that object (the memory address for practical purposes - but this is implementation specific) and is used as the hashcode for inserting into HashMap.

So in Java you can have a HashMap<HashMap<Integer, Integer>, Integer>

In Python some_dict = {{1: 1}: 1} will give you TypeError: unhashable type: 'dict'

Upvotes: 0

Bill Gross
Bill Gross

Reputation: 516

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.

Upvotes: 1

user240515
user240515

Reputation: 3207

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.

Upvotes: 21

Dave Kirby
Dave Kirby

Reputation: 26552

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.

Upvotes: 5

user3850
user3850

Reputation:

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

Upvotes: 1

Ben James
Ben James

Reputation: 125119

Short answer: because they are mutable containers.

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

Upvotes: 48

Related Questions