Reputation: 14335
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
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
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
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
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
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
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