Reputation: 8870
On the console I typed in
>>> class S(str): pass
...
>>> a = 'hello'
>>> b = S('hello')
>>> d = {a:a, b:b}
>>> d
{'hello': 'hello'}
>>> type(d[a])
<class '__main__.S'>
>>> type(d[b])
<class '__main__.S'>
I thought at first that the reason that d
only kept one pair was because hash(a)
and hash(b)
returned the same values, so I tried:
>>> class A(object):
... def __hash__(self):
... return 0
...
>>> class B(object):
... def __hash__(self):
... return 0
...
>>> d = {A():A(),B():B()}
>>> d
{<__main__.A object at 0x101808b90>: <__main__.A object at 0x101808b10>, <__main__.B object at 0x101808d10>: <__main__.B object at 0x101808cd0>}
Now I'm confused.
How come in the first code listing, d
only kept one pair, but in the second listing d
both keys were kept despite having same hash?
Upvotes: 7
Views: 148
Reputation: 19153
The hash does not determine the unique key in a dictionary. In some ways, hash functions are an "implementation detail", in that they determine how the dictionary internally stores its entries. a == b implies hash(a) == hash(b), but the converse does not hold in general. Two keys also need to be equal to each other (when applying the == operator) to be treated as equivalent keys in a dictionary.
Upvotes: 4
Reputation: 677
The keys are different for the first and second objects. As they are objects the key is some readable equivalent of the object not a string.
Upvotes: 0
Reputation: 251383
The two objects in your original example were collapsed not because they have the same hash, but because they compare equal. Dict keys are unique with respect to equality, not hash. Python requires that any two objects that compare equal must have the same hash (but not necessarily the reverse).
In your first example, the two objects are equal, since they both have the str
equality behavior. Since the two objects compare equal, they are collapsed to one. In the second example, they don't compare equal. By default user-defined classes use identity for equality --- that is, each object compares equal only to itself. So your two objects are not equal. It doesn't matter than they have the same hash.
Upvotes: 8
Reputation: 798626
If you want a type to be hashable then you must also define __eq__()
. str
defines __eq__()
properly, but A
and B
do not.
Upvotes: 2