确定 Python 的 hash() 返回的值范围



我想将 Python 的 hash() 函数返回的值映射到 0 到 1 范围内的浮点数。在我的系统上,我可以这样做

scale = 1.0/(2**64)
print hash(some_object)*scale+0.5

但是,我知道这在 32 位系统上会有所不同。很可能我永远不会在其他任何地方运行此代码,但我仍然想知道是否有办法以编程方式确定 Python 内置hash()函数可以返回的最大值和最小值。

(顺便说一下,我这样做的原因是我正在开发一个数值模拟,我需要从给定的 Numpy 数组中始终如一地生成相同的伪随机数。我知道内置哈希不会有最好的统计数据,但它很快,所以用它来测试很方便。

在Python 2.7中,hash()返回一个int,所以sys.maxint应该让你了解它的范围。

Python>= 3.2 具有sys.hash_info,它返回一个命名元组,其中包含一个具有哈希值位宽的键width。 示例:(为便于阅读而添加了换行符(

Python 3.7.3 (default, Jul 25 2020, 13:03:44) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.hash_info
sys.hash_info(
    width=64,
    modulus=2305843009213693951,
    inf=314159,
    nan=0,
    imag=1000003,
    algorithm='siphash24',
    hash_bits=64,
    seed_bits=128,
    cutoff=0
)

如图所示,我的机器上的 Python 使用 64 位哈希。

请注意,如果类实现__hash__()但返回超出此位宽的整数,则只会将其截断。

这不是对你主要问题的回答,而是对你的细则的回答。 numpy RNG 将numpy数组作为种子(在内部对其进行哈希处理(:

>>> import numpy
>>> a = numpy.arange(1000)
>>> b = a.copy()
>>> b[-1] = 0
>>> r1 = numpy.random.RandomState(a)
>>> r2 = numpy.random.RandomState(b)
>>> r3 = numpy.random.RandomState(a)
>>> r1.rand()
0.9343370187421804
>>> r3.rand()
0.9343370187421804
>>> r2.rand()
0.4651506189783071

hash()调用传入对象上的__hash__钩子。该钩子应返回一个整数。

由于 Python int的大小仅受内存限制,因此理论上hash()可以返回的值没有真正的上限。

如果要跟踪 Python 对象如何实现此目的,请在 Objects/ 目录中搜索tp_hash槽,或查找PyObject_Hash函数调用以查看集合、字典和其他代码如何使用这些槽的值。

CPython 长整数对象本身将返回值限制为 C 长整型。

内部而言,CPython type tp_hash 函数将从 Python __hash__ 函数返回的任何值转换为该值的 Python long int 哈希值;因此,大于 sys.maxint 的哈希值将通过再次对该值调用 hash() 来转换。

所以在实践中,hash()应该返回仅限于 sys.maxint 的值。

在 Python 3 中,引入了一种新的类型,Py_hash_t ;在某些 64 位平台上,C long 仍然限制为仅 32 位,但 Py_hash_t 的大小与指针相同,在任何 64 位平台上为您提供 64 位。在 Python 3 上,sys.maxsize值正确反映了最大值;它返回平台上指针可以容纳的最大值。

最新更新