Pas*_*ten 1 python hash dictionary python-3.x
我有两个类的实例,我想解析为字典中的相同键:
class CustomClass():
def __hash__(self):
return 2
a = CustomClass()
b = CustomClass()
dicty = {a : 1}
Run Code Online (Sandbox Code Playgroud)
这里,a和b不等于键:
>>> a in dicty
True
>>> b in dicty
False
Run Code Online (Sandbox Code Playgroud)
哈希到底发生了什么?看起来CustomClass的第二个实例应该与散列相匹配?这些哈希值与之不匹配的是什么?
我刚刚发现实际的课程正在被散列.那么如何为类添加自定义词典键(即当我尝试使用类作为词典的键时,应该如何存储以使a和b匹配)?
请注意,在这种情况下,我不关心保持链接到字典中的原始对象,我可以使用一些不可用的密钥对象; 只是重要的是他们解决了同样的问题.
编辑:
也许需要对我想要解决的实际案例提出一些建议.
我有包含boolean np.arraysof shape的类(8,6).我想对这些进行散列,这样无论何时将此对象放入字典中,都会对这些值进行比较.根据这个答案,我从他们身上做了一个小小的.我注意到它有一个__cmp__(感谢thefourtheye显示我必须看那里).然而,我的类可以被更新,所以我只喜欢凑时,我实际上是试图把它变成一本字典的np.array,而不是启动(因此存储哈希的bitarray每当我初始化,因为np.array可能会被更新,因此哈希不再是真实的表示.我知道每当我更新np.array时,我也可以更新散列值,但我更喜欢只散列一次!
你打破之间的合同__hash__,__cmp__和__eq__.引用__hash__文档,
如果一个类没有定义一个
__cmp__()或一个__eq__()方法,它也不应该定义一个__hash__()操作 ; 如果它定义__cmp__()或__eq__()不定义__hash__(),它的实例将不能在散列集合中使用.如果一个类定义了可变对象并实现了一个__cmp__()或__eq__()方法,那么它就不应该实现__hash__(),因为hashable集合实现要求对象的散列值是不可变的(如果对象的散列值改变,它将在错误的散列桶中).用户定义的类默认具有
__cmp__()和__hash__()方法; 与它们相比,所有对象都比较不相等(除了它们自己)并x.__hash__()返回一个适当的值,这x == y意味着它x is y和hash(x) == hash(y).
在您的情况下,哈希值对于两个对象是相同的,并且哈希冲突在任何哈希实现中都很常见.因此,Python将正在查找的对象与help __eq__方法进行比较,并发现被搜索的实际对象与已存储的对象不同.这就是b in dicty返回的原因False.
因此,要解决您的问题,请定义自定义__eq__函数,如下所示
class CustomClass():
def __init__(self):
self.data = <something>
def __hash__(self):
# Find hash value based on the `data`
return hash(self.data)
def __eq__(self, other):
return self.data == other.data
Run Code Online (Sandbox Code Playgroud)
注意: __hash__对于给定对象,值应始终相同.因此,请确保data在最初分配后永远不会更改.否则你永远无法从字典中获取对象,因为如果它在稍后的时间点发生变化,则hash值data将不同.