Python字典没有分配所有键或项目

时间:2016-05-04 03:50:06

标签: python dictionary

我创建了以下字典

exDict = {True: 0, False: 1, 1: 'a', 2: 'b'}

当我打印exDict.keys()时,它给了我一个发电机。好的,所以我将它强制列入清单,它给了我

[False, True, 2]

为什么不在那里?当我打印exDict.items()它给了我

[(False, 1), (True, 'a'), (2, 'b')]

任何人都猜测这里发生了什么?我很难过。

4 个答案:

答案 0 :(得分:28)

这是因为True == 1(和False == 0,但您没有0作为密钥)。你必须以某种方式重构你的代码或数据,因为dict认为密钥是相同的,如果它们是“相等的”(而不是is)。

答案 1 :(得分:12)

您看到的是python强制1等于True

您会看到您打印的字典是:

False  1
True   a
2      b

意图将值a分配给1,而True的值已重新分配给a

根据Python 3 Documentation

  

布尔类型是整数类型的子类型,布尔值在几乎所有上下文中的行为分别类似于值0和1 ,例外情况是转换为字符串时,字符串“False”或“True”分别返回。

强调我的。

注意:在python 2.X中TrueFalse可以重新分配,因此无法保证此行为。

答案 2 :(得分:5)

Python将1视为~/target-dir (some-branch)$ mkdir /tmp/tmp-target-dir ~/target-dir (some-branch)$ cp -r * /tmp/tmp-taregt-dir ~/target-dir (some-branch)$ git checkout -f master ~/target-dir (master)$ cp -r /tmp/tmp-target-dir/* . 。布尔类型是整数类型

的子类型
True

答案 3 :(得分:2)

如果在dict python中插入键值对,则检查该键是否已存在,如果该键存在,则将替换当前值。

此检查的确如下:

def hash_and_value_equal(key1, key2):
    return hash(key1) == hash(key2) and key1 == key2

因此,不仅价值必须相等,而且hash也是如此。不幸的是,您True1以及False0将被视为相同的密钥:

>>> hash_and_value_equal(0, False)
True

>>> hash_and_value_equal(1, True)
True

因此他们会替换值(而不是键):

>>> a = {1: 0}
>>> a[True] = 2
>>> a
{1: 2}

>>> a = {False: 0}
>>> a[0] = 2
>>> a
{False: 2}

我已经展示了手动添加密钥的情况,但使用dict literal时所采取的步骤是相同的​​:

>>> a = {False: 0, 0: 2}
>>> a
{False: 2}

dict - 内置:

>>> a = dict(((0, 0), (False, 2)))
>>> a
{0: 2}

如果您编写自己的类并希望将它们用作词典中的潜在键,这可能非常重要。这取决于您__eq____hash__的实施情况,并且不会替换相等但不相同的键的值:

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

所以这些不会取代现有的整数键:

>>> a = {1: 2, IntContainer(1): 3, 2: 4}
>>> a
{1: 2, <__main__.IntContainer at 0x1ee1258fe80>: 3, 2: 4}

或被认为是相同密钥的东西:

class AnotherIntContainer(IntContainer):
    def __hash__(self):
        # Not offsetted hash (collides with integer)
        return hash(self.value)

>>> hash_and_value_equal(1, AnotherIntContainer(1))
True

现在将替换整数键:

>>> a = {1: 2, AnotherIntContainer(1): 5}
>>> a
{1: 5}

唯一非常重要的是要记住,如果对象及其散列相等,字典键的结果是相等的。