我创建了以下字典
exDict = {True: 0, False: 1, 1: 'a', 2: 'b'}
当我打印出exDict.keys()
时,它返回一个生成器。好的,我把它转换为列表,然后它就给了我
[False, True, 2]
为什么没有1?当我打印exDict.items()
时,它给了我
[(False, 1), (True, 'a'), (2, 'b')]
有人猜测这里发生了什么事吗?我很困惑。
我创建了以下字典
exDict = {True: 0, False: 1, 1: 'a', 2: 'b'}
当我打印出exDict.keys()
时,它返回一个生成器。好的,我把它转换为列表,然后它就给了我
[False, True, 2]
为什么没有1?当我打印exDict.items()
时,它给了我
[(False, 1), (True, 'a'), (2, 'b')]
有人猜测这里发生了什么事吗?我很困惑。
这种情况发生是因为True == 1
(同样地,False == 0
,但你没有将0
作为键)。你需要进行代码或数据的重构,因为dict
在判断键是否相同时会考虑它们是否“相等”(而不是is
)。
a
)。这也是有意义的,如果我们考虑到字典可能是迭代地从文字构建的,因此"稍后"的映射将覆盖"早期"的映射。 - mikołak1
强制转换为True
。你会看到你打印的字典是:False 1
True a
2 b
本来想将值 a
分配给 1
,但实际上将 a
重新分配为 True
的值。
根据Python 3 文档:
布尔类型是整数类型的子类型,在几乎所有情况下,布尔值的行为与值 0 和 1 相同,唯一的例外是在转换为字符串时,分别返回字符串 "False" 或 "True"。
强调是我的。
注意:在 python 2.X 中,可以重新分配 True
和 False
,因此无法保证这种行为。
Python将1视为True
。布尔类型是整数类型的子类型。
In [1]: a = {}
In [2]: a[True] = 0
In [3]: 1 in a.keys()
Out[3]: True
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字面值
时采取的步骤是相同的:
>>> 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}
唯一非常重要的是要记住,如果对象和它们的哈希值相等,则字典键被视为相等。
(True, 'a')
,这是1
的值。 - njzk2