Python冻结集合的持久哈希
你怎么把一堆嵌套的Python frozenset对象转换成一个独特的整数,这个整数在不同的Python会话和平台上都是一样的呢?
比如说,我在不同的平台上用hash()得到的值是不一样的。
32位
Python 2.6.5 (r265:79063, Apr 16 2010, 13:09:56)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a=frozenset([frozenset([1,2,3]),frozenset(['a','b','c'])]);
>>> hash(a)
1555175235
64位
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41)
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a=frozenset([frozenset([1,2,3]),frozenset(['a','b','c'])]);
>>> hash(a)
-6076998737938213053
2 个回答
0
你也可以自己创建一个哈希函数:
def hash(fs):
res = 1
for v in fs:
res = (res*31 + v) % 2**30
return res
这个哈希函数不一定是唯一的,但它和内置的集合哈希函数差不多好,而且你可以完全控制它在不同平台上的结果。
8
你如何将一堆嵌套的Python frozenset对象转换成一个在不同Python会话和平台上都相同的唯一整数呢?
据我所知,哈希值并不一定是唯一的。实际上,在查找表(比如字典)中,哈希冲突是很常见的。
不过,如果你想要一个在不同平台上都一致的、但不一定唯一的“哈希”,我建议你使用标准库中的hashlib。我没有机会在不同的平台上试验,但我相信那里的大多数算法(比如MD5)都是与平台无关的。
我会将排序后的集合的序列化版本输入到哈希算法中,这样可以确保用于哈希的字符串始终是相同的。
编辑:我想加一个基本的例子:
>>> import cPickle as pkl
>>> import hashlib as hl
>>> s = frozenset([1,2,3])
>>> p = pkl.dumps(sorted(s)) #make sure you use the same pickle protocol on all platform!
'(lp1\nI1\naI2\naI3\na.'
>>> h = hl.md5(p)
<md5 HASH object @ 0xb76fb110>
>>> h.digest()
"\x89\xaeG\x1d'\x83\xa5\xbd\xac\xa7\x1c\xd9\x1d/2t" #this should be consistent