Consider the following Python interpreter shell session:
>>> class D(dict):
... def __hash__(self):
... return id(self)
...
>>> d1 = D({'a': 'b'})
>>> d2 = D({'a1': 'b1'})
>>> t = {d1: 1, d2: 2}
>>> t[d1]
1
>>> t[d2]
2
Why doesn't dict's __hash__ default to id()? What led to the design decision of forbidding to use mutable entities as dictionary keys?
Why doesn't dict's
__hash__default toid()?
Because that violates the fundamental invariant that equal objects have equal hashes. If dicts used their id for their hash, then you'd have interactions like the following:
>>> x, y = {}, {}
>>> x == y
True
>>> hash(x) == hash(y)
False
>>> x[{}] = 3
>>> x[{}]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: {}
The behavior would be confusing, inconsistent, and not useful.
dict's __hash__ doesn't default to id() because it would defeat the fundamental purpose of hash tables.
As linked in this comment on another question's answer:
And see the Python FAQ entry Why must dictionary keys be immutable?
The linked documentation says the following (with additional explanation for those who want to read more):
The hash table implementation of dictionaries uses a hash value calculated from the key value to find the key. If the key were a mutable object, its value could change, and thus its hash could also change. But since whoever changes the key object can’t tell that it was being used as a dictionary key, it can’t move the entry around in the dictionary. Then, when you try to look up the same object in the dictionary it won’t be found because its hash value is different. If you tried to look up the old value it wouldn’t be found either, because the value of the object found in that hash bin would be different.
Emphasis added.
Basically, the hash table is only useful if it only holds immutable values. Workarounds like id() defeat the entire purpose, because (as explained in the bold portion of the above quote) you wouldn't find values that you tried to look up.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With