Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why mutable entities cannot be a dictionary key?

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?

like image 932
d33tah Avatar asked Dec 13 '25 08:12

d33tah


2 Answers

Why doesn't dict's __hash__ default to id()?

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.

like image 114
user2357112 supports Monica Avatar answered Dec 15 '25 14:12

user2357112 supports Monica


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.

like image 29
TigerhawkT3 Avatar answered Dec 15 '25 16:12

TigerhawkT3



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!