我想将 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
值正确反映了最大值;它返回平台上指针可以容纳的最大值。