字典中具有其他数据类型的布尔键

2024-03-28 20:06:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我浏览了一些python字典的链接,找到了这个。在

我好像不明白下面发生了什么。在

dict1 = {1:'1',2:'2'}
print dict1

输出

^{pr2}$

但是如果我在字典里加上一个布尔键,它会给出一些奇怪的东西。在

dict2 = {True:'yes',1:'1',2:'2'}
print dict2

输出

{True:'1',2:'2'}

只有在字典中加入布尔值时才会发生这种情况吗?在


Tags: true字典链接情况yesprintpr2dict1
3条回答

在Python中,dict的keys被存储为hash-slot对,其中{}由某个{}下的key-value对组成。因此,在dict中通过key获得{}的实际搜索过程如下:

  1. 获取提供的密钥hash(key)的哈希值
  2. hash值下找到对应的slot
  3. 迭代slot以找到满足tkey == key的目标键(将其命名为tkey),然后返回该键的value。在

因此,在Python中,相同的keys可能具有不同的值,如果它们的keys不相同,{}可能具有不同的值。hash值由__hash__方法计算而key是否相同由__eq__方法(或__cmp__)控制。
例如

class A:
    def __hash__(self):
        return 1

    def __eq__(self, other):
        return False

现在,A的所有实例都具有相同的散列值1,但所有实例都不同(包括与自身的比较):

^{pr2}$

让我们看看在dict中充当keys时它们可以是什么:

b = {
    a1: 1,
    a2: 2,
}
print(b)
# {<__main__.A object at 0x000002DDCB505DD8>: 1, 
# <__main__.A object at 0x000002DDCB505D30>: 2}

为什么True和{}不能同时存在于一个dict中

在这个问题中(或者在Python中的大多数情况下),等价的hash表示等价的{}。在

print(hash(True) == hash(1)) # True
print(True == 1) # True

结果(或者说,这个等式机制的原因)是每个hash slot只有一个key-value对(因为keys是相等的)。这使得搜索值非常快,因为不需要在槽上迭代。你仍然可以在相同的代码中实现相同的键

class exint(int):
    def __init__(self, val):
        self.val = val
    def __eq__(self, other):
        return False
    def __hash__(self):
        return int.__hash__(self.val)

a = exint(1)

print(a) # 1
b = {
    a: 1,
    True: 2,
}
print(b) # {1: 1, True: 2}

Python dict是一个哈希映射,它通过一个散列函数索引其键,以便在内存中快速查找。由于hash(1) is hash(True)的求值是True,所以Python将两者视为几乎相同的键。因此,在Python中的任何类型的散列存储中都不能同时拥有1和{}(不实现自己的哈希函数)。在

问题是True是一个值为1的内置枚举。因此,哈希函数将True视为另一个1,并且。。。好吧,正如你所见,这两个人在重新绘制地图时会感到困惑。是的,有一些明确的规则描述Python如何解释这些,但是在这个级别上,您可能不关心False=0和True=1之后的任何内容。在

您看到的标签(例如True vs 1)是在第一个引用处设置的。例如:

>>> d = {True:11, 0:10}
>>> d
{0: 10, True: 11}
>>> d[1] = 144
>>> d
{0: 10, True: 144}
>>> d[False] = 100
>>> d
{0: 100, True: 144}

注意这是如何工作的:每个字典条目显示每个给定值(0/False和1/True)的第一个标签。与任何赋值一样,显示的值是最后一个。在

相关问题 更多 >