我创建了以下字典
exDict = {True: 0, False: 1, 1: 'a', 2: 'b'}
当我打印exDict.keys()
时,它给了我一个发电机。好的,所以我将它强制列入清单,它给了我
[False, True, 2]
为什么不在那里?当我打印exDict.items()
它给了我
[(False, 1), (True, 'a'), (2, 'b')]
任何人都猜测这里发生了什么?我很难过。
答案 0 :(得分:28)
这是因为True == 1
(和False == 0
,但您没有0
作为密钥)。你必须以某种方式重构你的代码或数据,因为dict
认为密钥是相同的,如果它们是“相等的”(而不是is
)。
答案 1 :(得分:12)
您看到的是python强制1
等于True
。
您会看到您打印的字典是:
False 1
True a
2 b
意图将值a
分配给1
,而True
的值已重新分配给a
。
布尔类型是整数类型的子类型,布尔值在几乎所有上下文中的行为分别类似于值0和1 ,例外情况是转换为字符串时,字符串“False”或“True”分别返回。
强调我的。
注意:在python 2.X中True
和False
可以重新分配,因此无法保证此行为。
答案 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
也是如此。不幸的是,您True
和1
以及False
和0
将被视为相同的密钥:
>>> 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}
唯一非常重要的是要记住,如果对象及其散列相等,字典键的结果是相等的。