为什么dict和lru_cache将所有散列为0的键区别对待?

时间:2019-08-25 04:50:02

标签: python dictionary hash

由于以下值:00.00jFalse""(空字符串)的哈希值均为{{1 }}我希望将这些值中的每一个用作0键会导致dict仅包含一项。但是,由于某些原因,对空字符串键的处理方式有所不同,导致dict包含两个项目。

此外,如果将相同的键传递给使用dict装饰器缓存的函数,则即使它们具有相同的结果,缓存也会对@lru_cache( ... )0和空字符串进行不同的处理哈希值和类型检查在缓存中配置为0.0

为什么在两种情况下空字符串都被视为不同于数字0的键?为何在False情况下,0被当作不同于0.0的键和空字符串?

lru_cache

输出显示:

keys = [0, 0.0, 0j, False, ""]
values = "abcde"

print("\nthe hash value of each key IS 0 is", 
      all(hash(k) is 0 for k in keys))

mydict = dict(zip(keys, values))
print("\nHowever a dict treats empty string differently:")
print(mydict)


from functools import lru_cache

@lru_cache(maxsize=100, typed=False)
def compute(x):
    print("lru_cache says: haven't", x, "before")

print("\nwhereas lru_cache, even with typing turned off,")
print("treats 0, 0.0, and empty string differently:\n")
for k in keys:
    compute(k)

1 个答案:

答案 0 :(得分:2)

字典不仅使用散列来确定元素是否不同,还会检查它们是否相等。

重复元素是由__eq__确定的相等元素。 0 == ""返回False的事实可以解释您看到的行为。

>>> 0 == 0.0
True
>>> 0 == 0j
True
>>> 0 == False
True
>>> 0 == ""
False