python - 为什么 dict 和 lru_cache 对所有哈希为 0 的键的处理方式不同?

标签 python dictionary hash

由于值:00.00jFalse"" (空字符串)的哈希值均为 0 我预计使用这些值中的每一个作为 dict 键将得到一个 dict 仅包含一项。但是,由于某种原因,空字符串键的处理方式有所不同,导致 dict 包含两个项目。

此外,如果将相同的键传递给使用 @lru_cache( ... ) 装饰器缓存的函数,则生成的缓存将处理 00.0 和空字符串不同,即使它们具有相同的哈希值并且类型检查在缓存中配置为 False

为什么在这两种情况下,空字符串都被视为与数字 0 不同的键?为什么 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)

输出显示:

the hash value of each key IS 0 is True

However a dict treats empty string differently:
{0: 'd', '': 'e'}

whereas lru_cache, even with typing turned off,
treats 0, 0.0, and empty string differently:

lru_cache says: haven't 0 before
lru_cache says: haven't 0.0 before
lru_cache says: haven't  before 

最佳答案

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

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

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

关于python - 为什么 dict 和 lru_cache 对所有哈希为 0 的键的处理方式不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57643327/

相关文章:

python : Why use "list[:]" when "list" refers to same thing?

java - 如何确保我的 map 在我的构建器模式中设置后永远不会被修改?

c++ - 如何采集同类型Map的值

c - 相当于 Linux 命令中的 md5 哈希

arrays - 如果具有该值的散列不存在,则在数组中添加散列,否则扩展现有散列

python - 当其他应用程序运行时,线程运行速度不够快

python - 我将如何在 python 中发送电子邮件?此代码无效

python - 在python字典中用 "None"替换空值

java - 如何在 Java 中存储(和读取)大型数组/映射/其他内容?

ruby - 根据每个嵌套数组的第一个元素对 Ruby 数组重新排序