- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
显然 python 将允许我散列生成器表达式,如 (i for i in [1, 2, 3, 4, 5])
>>> hash(i for i in [1, 2, 3, 4, 5])
8735741846615
然而,仔细检查后,无论我将什么生成器放入该哈希值,该哈希值始终相同!
>>> hash(i for i in range(2))
8735741846615
>>> hash(i for i in [1, 2, 3, 4, 5, 6])
8735741846615
>>> hash(i for i in [0, 1, 2, 3, 4, 5, 6])
8735741846615
为什么会这样?为什么甚至允许对生成器进行哈希处理?
我需要这样做,因为我要将内容存储在字典缓存中。您可以通过传递对象列表来访问缓存中的条目。但是具有不同项目的某些列表组仍应指向相同的条目,因为这里唯一重要的是每个列表项目中一个属性的整数值。因此,它们应该仅基于这些整数值进行哈希处理,而不是与项目本身相关的任何内容,以避免不必要的缓存未命中。
我知道你总是可以将表达式转换为元组,但我想问你是否可以通过简单地使用没有元组容器的生成器的输出来绕过它,类似于 sum()
可以用于这样的事情。
最佳答案
所以这里其实有两个问题:
对于 2,答案很简单:在这种情况下,哈希基于对象的 id
。由于您实际上并不存储该对象,因此它的内存会被重用。这意味着下一个生成器具有相同的 id
和哈希值。
对于 1,答案是“因为他们可以”。 hash
主要用于 dict
、set
和其他允许识别对象的情况。这些情况设置了 a == b
也意味着 hash(a) == hash(b)
的约束(反之不受约束)。
现在,对于list
、dict
等集合,平等是基于内容的。例如,[1,2,3] == [1,2,3]
不管它们是否是相同的对象。这意味着如果向它们添加某些内容,它们的相等性会发生变化,因此它们的 hash
也会发生变化。因此,hash
是未定义的,因为它必须是常量才能在 dict
等中工作。
相比之下,生成器可以有任何内容。例如,考虑一个提供随机值的生成器。因此,按内容比较生成器是没有意义的。他们只是通过身份进行比较。因此,对于生成器,a == b
等于 id(a) == id(b)
。反过来,这意味着基于 id(a)
的 hash(a)
将始终通过对 hash
的相等性来满足约束。
关于python - 散列生成器表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38174211/
我是一名优秀的程序员,十分优秀!