我可以安全地使用包含64位整数(long)的元组的哈希作为python字典中的唯一键吗?

时间:2010-10-05 12:50:46

标签: python dictionary hash hashtable tuples

我必须在dict中存储具有两个属性(ida和idb)的对象。这两个属性都是64位正整数,我只能存储一个对象,用于ida和idb的唯一排列(顺序重要的组合)。例如:

obj1 = SomeClass(ida=5223372036854775807, idb=2)
obj2 = SomeClass(ida=2, idb=5223372036854775807)
obj3 = SomeClass(ida=5223372036854775807, idb=2)

由于对象本身是可变的,我使用元组'(ida,idb,)'的哈希作为键。按照这个例子,考虑一下:

d = {}
# storing obj1
k1 = hash((obj1.ida, obj1.idb,))
d[k1] = obj1
# storing obj2
k2 = hash((obj2.ida, obj2.idb,))
d[k2] = obj2
# storing obj3
k3 = hash((obj3.ida, obj3.idb,)) # note that k3 hash should be the same as k1
d[k3] = obj3
#at this point 'd' should contain only 'obj2' and 'obj3' since 'k1' == 'k3'

我在我的64位机器上测试了上面的例子,它按预期工作。

我有以下问题:

  • 如果两个大整数元组在元素或排序方面存在差异,是否有可能计算相同的哈希?
  • 在32位平台上怎么样?
  • 如果没有,是否有一种独立于平台的方式来保证上述示例无论ida和idb的值如何都能正常工作?

3 个答案:

答案 0 :(得分:2)

In [33]: hash?
  

返回对象的哈希值。两个具有相同的对象   value具有相同的哈希值。 反过来不一定正确,但是   可能

为什么不使用元组(ida,idb)作为密钥?

import pprint
class SomeClass(object):
    def __init__(self,ida,idb):
        self.ida=ida
        self.idb=idb
obj1 = SomeClass(ida=5223372036854775807, idb=2)
obj2 = SomeClass(ida=2, idb=5223372036854775807)
obj3 = SomeClass(ida=5223372036854775807, idb=2)

d={}
for obj in (obj1,obj2,obj3):
    d[obj.ida,obj.idb]=obj

pprint.pprint(d)
# {(2, 5223372036854775807L): <__main__.SomeClass object at 0xb78839ec>,
   (5223372036854775807L, 2): <__main__.SomeClass object at 0xb7883a0c>}

答案 1 :(得分:1)

就像伊格纳西奥所说,你可以有哈希碰撞。你为什么不只使用元组本身?元组是不可变的,看起来你的ida和idb是(不可变的)整数。

答案 2 :(得分:0)

只有2 **&lt;字数&gt;可能的哈希,所以你必须运行一个128位版本的Python,甚至可以存储所有(2 ** 64)** 2个可能的哈希值。是的,它可能仍然可能发生碰撞。如果需要存储唯一对象,请使用set;只需以理智的方式定义__hash__()__eq__()