我必须在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位机器上测试了上面的例子,它按预期工作。
我有以下问题:
答案 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__()
。