由于值:0
、0.0
、0j
、False
和 ""
(空字符串)的哈希值均为 0
我预计使用这些值中的每一个作为 dict
键将得到一个 dict
仅包含一项。但是,由于某种原因,空字符串键的处理方式有所不同,导致 dict
包含两个项目。
此外,如果将相同的键传递给使用 @lru_cache( ... )
装饰器缓存的函数,则生成的缓存将处理 0
、0.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/