假设我们有一个这样的自定义节点类:
class Node:
def __init__(self, val, next, random):
self.val = val
self.next = next
self.random = random
节点对象可以用作字典的键吗?我的理解是,对象必须是不可变的且可哈希化的,才有资格用作字典键,因为可变对象会导致哈希值变化,但该对象是可变的,因此不应用作键。可以将自定义可变类用作字典的键吗?答案似乎是肯定的,所以适当的问题是如何?
答案 0 :(得分:1)
在this线程上的答案帮助我了解了它的工作原理。
这里的想法是确保您的自定义对象实现哈希和相等方法。
平等方法应以始终将两个逻辑等效对象视为相等的方式实施。对于此处给定的 Node 对象,如果两个节点的所有属性都相同,则将其视为相等。因此,我们可以构建一个包含所有属性的元组的键。之所以可行,是因为元组是不可变的,因此我们基本上将创建一个不可变的对象,其中包含该对象的所有属性,并将使用此对象来计算哈希。
以下实现可确保两个逻辑等效的节点(具有相同的属性)具有相同的密钥,因此将为两个相等的节点生成相同的哈希值。
class Node:
def __init__(self, val, next, random):
self.val = val
self.next = next
self.random = random
def __key(self):
return (self.val, self.next, self.random)
def __hash__(self):
return hash(self.__key())
def __eq__(self, other):
if isinstance(other, Node):
return self.__key() == other.__key()
return NotImplemented
请注意,如果节点的任何属性发生更改,则它基本上会变成其他节点,并且很可能会导致产生不同的哈希值。我说的可能性最大,因为两个不同的节点最终可能具有相同的哈希值,所以这种现象称为哈希冲突。上面引用的链接具有相同的更多信息。