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

时间:2013-10-02 08:32:01

标签: python hash

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

执行此操作
scale = 1.0/(2**64)
print hash(some_object)*scale+0.5

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

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

4 个答案:

答案 0 :(得分:8)

在Python 2.7中hash()会返回int,因此sys.maxint会让您了解其范围。

答案 1 :(得分:1)

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

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

如果要跟踪Python对象如何实现此功能,请在Objects/ directory中搜索tp_hash插槽,或查找PyObject_Hash函数调用以查看这些插槽的值如何由集和词典以及其他代码使用。

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

从某种程度上说,CPython type tp_hash函数将转换从Pyt​​hon __hash__函数返回的任何值,该值超出了Python long int的范围,超出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值正确反映了最大值;它返回平台上指针可以容纳的最大值。

答案 2 :(得分:1)

这不是你的主要问题的真正答案,而是对你的细则的回答。 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

答案 3 :(得分:1)

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__(),但返回一个超出此位宽的整数,则为 it will simply be truncated

相关问题