Dictionary for python

On the console, I typed

>>> 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'> 

At first I thought that the reason d contained only 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 am confused. How was only one pair stored in the first code list d , but in the second listing d both keys were saved, despite the same hash?

+7
source share
4 answers

The two objects in your original example were collapsed, not because they have the same hash, but because they compare the same. Dictate keys are unique with respect to equality, not to hash. Python requires that any two objects that compare the same must have the same hash (but not necessarily the opposite).

In the first example, two objects are equal, since both of them have str equality behavior. Since both objects are compared equal, they collapse into one. In the second example, they are not compared equal. By default, user classes use identification for equality --- that is, each object is compared with an equal only to itself. So your two objects are not equal. It doesnโ€™t matter since they have the same hash.

+8
source

The hash does not define a unique key in the dictionary. In a sense, hash functions are "implementation details" because they determine how the dictionary internally stores its records. a == b means hash (a) == hash (b), but the opposite is not true at all. Two keys must also be equal to each other (when using the == operator), which should be considered as equivalent keys in the dictionary.

+4
source

If you want the type hashable , then you must also define __eq__() . str correctly defines __eq__() , but A and B do not.

+2
source

The keys are different for the first and second objects. Because they are objects, a key is some readable equivalent of an object, not a string.

0
source

All Articles