If you insert a key-value pair into a python dict check, if the key already exists, and if it exists, it will replace the current value.
This check does something like this:
def hash_and_value_equal(key1, key2): return hash(key1) == hash(key2) and key1 == key2
This means that not only the values โโshould be equal, but also their hash . Unfortunately for you, True and 1 , but also False and 0 will be considered equal keys:
>>> hash_and_value_equal(0, False) True >>> hash_and_value_equal(1, True) True
and therefore they replace the value ( but not the key):
>>> a = {1: 0} >>> a[True] = 2 >>> a {1: 2} >>> a = {False: 0} >>> a[0] = 2 >>> a {False: 2}
I showed the case of manually adding the key, but the steps taken are the same when using dict literal :
>>> a = {False: 0, 0: 2} >>> a {False: 2}
or dict -builtin:
>>> a = dict(((0, 0), (False, 2))) >>> a {0: 2}
This can be very important if you write your own classes and want to use them as potential keys inside dictionaries. Depending on your implementation of __eq__ and __hash__ they will and will not replace the values โโof the same, but not identical keys:
class IntContainer(object): def __init__(self, value): self.value = value def __eq__(self, other): return self.value == other def __hash__(self):
Thus, they will not replace existing integer keys:
>>> a = {1: 2, IntContainer(1): 3, 2: 4} >>> a {1: 2, <__main__.IntContainer at 0x1ee1258fe80>: 3, 2: 4}
or something that is considered identical:
class AnotherIntContainer(IntContainer): def __hash__(self):
Now they will replace the whole keys:
>>> a = {1: 2, AnotherIntContainer(1): 5} >>> a {1: 5}
The only thing important is to remember that dictionary keys are kept equal if the objects and their hash are equal.