If you insert a key-value pair in a dict python checks 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
So not only must the values be equal but also their hash. Unfortunatly 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've showed the case of adding a key manually but the steps taken are the same when using the dict literal:
>>> a = {False: 0, 0: 2}
>>> a
{False: 2}
or the dict-builtin:
>>> a = dict(((0, 0), (False, 2)))
>>> a
{0: 2}
This can be very important if you write own classes and want to use them as potential keys inside dictionaries. Depending on your implementation of __eq__ and __hash__ these will and won't replace the values of equal 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):
# Just offsetting the hash is enough because it also checks equality
return hash(1 + self.value)
>>> hash_equal(1, IntContainer(1))
False
>>> hash_equal(2, IntContainer(1))
False
So these won't 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 as identical key:
class AnotherIntContainer(IntContainer):
def __hash__(self):
# Not offsetted hash (collides with integer)
return hash(self.value)
>>> hash_and_value_equal(1, AnotherIntContainer(1))
True
These will now replace the integer keys:
>>> a = {1: 2, AnotherIntContainer(1): 5}
>>> a
{1: 5}
The only really important thing is to keep in mind that dictionary keys are consered equal if the objects and their hash is equal.
(True, 'a'), which is the value for1.