Python 实现字典的自定义键,以便同一类的两个实例匹配
我有两个类的实例,我想将它们解析为字典中的同一个键:Python 实现字典的自定义键,以便同一类的两个实例匹配,python,python-3.x,dictionary,hash,Python,Python 3.x,Dictionary,Hash,我有两个类的实例,我想将它们解析为字典中的同一个键: class CustomClass(): def __hash__(self): return 2 a = CustomClass() b = CustomClass() dicty = {a : 1} 这里,a和b作为键并不相等: >>> a in dicty True >>> b in dicty False 哈希到底发生了什么;看起来C
class CustomClass():
def __hash__(self):
return 2
a = CustomClass()
b = CustomClass()
dicty = {a : 1}
这里,a和b作为键并不相等:
>>> a in dicty
True
>>> b in dicty
False
哈希到底发生了什么;看起来CustomClass的第二个实例应该与哈希匹配?这些哈希值不匹配的原因是什么
我刚刚发现实际的类是被散列的。那么,如何为类添加自定义字典键(即,当我尝试使用一个类作为字典键时,应该如何存储它以使a和b匹配)
请注意,在这种情况下,我不关心在字典中保留到原始对象的链接,我可以使用一些不可用的键对象;重要的是他们决心一致
编辑:
也许需要一些关于我想解决的实际案例的建议
我的类包含布尔
np。数组的形状(8,6)
。我想对这些值进行散列,这样每当将这个对象放入字典时,就会对这些值进行比较。我根据答案把它们做成了一个位数组。我注意到它在那里有一个\uu\cmp\uu
(感谢第四个显示我必须查看那里)。但是,我的类可以更新,所以我只想在实际尝试将np.array放入字典时对其进行散列,而不是在初始化时(因此每当我init时存储可散列位数组,因为np.array可能会被更新,因此散列不再是真正的表示)。我知道每当我更新np.array时,我也可以更新散列值,但我更喜欢只散列一次 \uuuuu散列\uuuuuu
仅确定将值放入哪个存储桶中。在bucket中,python总是调用\uuuuuuueq\uuu
,以确保它不会返回一个恰好具有相同哈希值但实际上不同的元素,因此您还需要实现自己的\uuuueq\uu
class CustomClass():
定义散列(自我):
返回2
定义(自身、其他):
返回散列(其他)=散列(自身)
a=自定义类()
b=自定义类()
dicty={a:1}
用口述法打印
用口述法打印b
用口述法打印“a”
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
仅确定将值放入哪个存储桶中。在bucket中,python总是调用\uuuuuuueq\uuu
,以确保它不会返回一个恰好具有相同哈希值但实际上不同的元素,因此您还需要实现自己的\uuuueq\uu
class CustomClass():
定义散列(自我):
返回2
定义(自身、其他):
返回散列(其他)=散列(自身)
a=自定义类()
b=自定义类()
dicty={a:1}
用口述法打印
用口述法打印b
用口述法打印“a”
您应该实现\uuuuu eq\uuuu
方法,以使对象可散列
。
文档中可散列的定义:
如果一个对象的散列值在处理过程中从不改变,那么它就是可散列的
它的生存期(它需要一个_hash _;()方法),并且可以
与其他对象相比(它需要一个_eq__()方法)。散列
比较相等的对象必须具有相同的哈希值
哈希性使对象可用作字典键和集合成员,因为这些数据结构在内部使用哈希值
您应该实现\uuuuueq\uuuu
方法,以使对象可散列
。
文档中可散列的定义:
如果一个对象的散列值在处理过程中从不改变,那么它就是可散列的
它的生存期(它需要一个_hash _;()方法),并且可以
与其他对象相比(它需要一个_eq__()方法)。散列
比较相等的对象必须具有相同的哈希值
哈希性使对象可用作字典键和集合成员,因为这些数据结构在内部使用哈希值
您违反了\uuuuuuuhash\uuuuuuu
、\uuucmp\uuuuu
和之间的合同。引用
如果类没有定义\uuu cmp\uuu()
或\uuu eq\uuuu()
方法,那么它也不应该定义\uu hash\uuuuu()
操作;如果它定义了\uu cmp\uu()
或\uu eq\uuu()
而不是\uuu hash\uuu()
,则其实例将无法在哈希集合中使用。如果类定义了可变对象并实现了\uuu cmp\uuu()
或\uuu eq\uuuu()
方法,那么它不应该实现\uu hash\uuuu()
,因为可哈希集合实现要求对象的哈希值是不可变的(如果对象的哈希值发生变化,它将位于错误的哈希桶中)
默认情况下,用户定义的类具有\uuuu cmp\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;使用它们,所有对象都比较不相等(除了它们自己)
和x。
返回一个适当的值,使得x==y
意味着x是y
和hash(x)==hash(y)
在您的例子中,两个对象的哈希值相同,并且在任何哈希实现中都是通用的。因此,Python将正在查找的对象与help\uuuuu eq\uuu
方法进行比较,发现正在搜索的实际对象与已存储在中的对象不同。这就是为什么dicty中的b
返回False
因此,要解决您的问题,还可以定义自定义\uuuuuuuuuuuuuuuuuuuuuuuuuuueq
函数,如下所示
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
class CustomClass():
定义初始化(自):
self.data=
定义散列(自我):
#基于`数据查找哈希值`
返回散列(self.data)
定义(自身、其他):
返回self.data==other.data
注意:\uuuuuuuuuuuuuuuuuuuu散列值对于给定对象应始终相同。因此,请确保数据
class CustomClass:
def __hash__(self):
return 2
def __eq__(self, other):
return type(self) is type(other) and type(self) is CustomClass