Python Dictionary Doesn't Have All The Keys Assigned, Or Items
Solution 1:
This happens because True == 1
(and False == 0
, but you didn't have 0
as a key). You'll have to refactor your code or data somehow, because a dict
considers keys to be the same if they are "equal" (rather than is
).
Solution 2:
What you are seeing is python coercing the 1
to be equal to the True
.
You'll see that the dictionary you print is:
False 1
True a2b
Where the value a
was meant to be assigned to the 1
, but instead the value for True
got reassigned to a
.
According to the Python 3 Documentation:
The Boolean type is a subtype of the integer type, and Boolean values behave like the values 0 and 1, respectively, in almost all contexts, the exception being that when converted to a string, the strings "False" or "True" are returned, respectively.
Emphasis mine.
Note: In python 2.X True
and False
can be re-assigned, so this behavior cannot be guaranteed.
Solution 3:
Python take the 1 as True
. And the Boolean type is a subtype of the integer type
In [1]: a = {}
In [2]: a[True] = 0
In [3]: 1 in a.keys()
Out[3]: True
Solution 4:
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:
defhash_and_value_equal(key1, key2):
returnhash(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:
classIntContainer(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 equalityreturnhash(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:
classAnotherIntContainer(IntContainer):
def__hash__(self):
# Not offsetted hash (collides with integer)returnhash(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.
Post a Comment for "Python Dictionary Doesn't Have All The Keys Assigned, Or Items"