Python 的 hash() 函数返回的最大值/最小值

Posted

技术标签:

【中文标题】Python 的 hash() 函数返回的最大值/最小值【英文标题】:Maximum/minimum value returned by Python's hash() function 【发布时间】:2021-06-06 03:42:40 【问题描述】:

上下文:构建一致的哈希算法。

Python 的 hash() 函数的 official documentation 声明:

返回对象的哈希值(如果有的话)。哈希值是整数。

但是,它没有明确说明函数是否映射到整数范围(具有最小值和最大值)。

来自其他基本类型值有界的语言(例如 C#/Java 的 Int.MaxValue),我知道 Python's likes to think in "unbounded" terms - 即在后台从 int 切换到 long

我是否假设hash() 函数也是无限的?或者它是有界的,例如映射到 Python 分配给max/min values of the "int-proper" 的内容——即在-21474836482147483647 之间?

【问题讨论】:

您已阅读docs.python.org/3/reference/datamodel.html#object.__hash__ 的说明? "在后台从 int 切换到 long。"在 Python 3 中不再存在这种区别,它在整个范围内都是 int,并且没有公开从“short int”到“long int”到“infinite”的切换。 【参考方案1】:

正如其他人指出的那样,文档中有一个错误的[1]注释:

hash() 将从对象的自定义 hash() 方法返回的值截断为 Py_ssize_t 的大小。

要回答这个问题,我们需要得到这个Py_ssize_t。经过一些研究,它似乎存储在sys.maxsize,尽管我希望在这里得到一些反馈。

我最终采用的解决方案是:

import sys
bits = sys.hash_info.width              # in my case, 64
print (sys.maxsize)                     # in my case, 9223372036854775807

# Therefore:
hash_maxValue = int((2**bits)/2) - 1    # 9223372036854775807, or +sys.maxsize
hash_minValue = -hash_maxValue          # -9223372036854775807, or -sys.maxsize

很高兴收到有关此问题的 cmets/反馈 - 在证明错误之前,这是公认的答案。


[1] 包含注释in the section dedicated to __hash__(),而不是专用于hash() 的注释。

【讨论】:

【参考方案2】:

来自文档

hash() 截断从对象的自定义 __hash__() 返回的值 方法到 Py_ssize_t 的大小。这通常是 8 个字节 64 位版本和 32 位版本上的 4 个字节。如果一个对象的__hash__() 必须在不同位大小的构建上互操作,请务必检查 所有支持的版本的宽度。一个简单的方法是使用 python -c "import sys; print(sys.hash_info.width)"。

更多细节可以在这里找到https://docs.python.org/3/reference/datamodel.html#object.__hash__

【讨论】:

以上是关于Python 的 hash() 函数返回的最大值/最小值的主要内容,如果未能解决你的问题,请参考以下文章

Python 3.3 中的哈希函数在会话之间返回不同的结果

第五天python3 内建函数总结

python编写程序,利用元组作为函数的返回值,求系列类型的最大值、最小值和元素个数

ruby / rails - hash max by:key不返回最大值

python

一致性hash