Python:自定义类可以用作字典的键吗?

时间:2019-11-26 22:43:11

标签: python-3.x hashmap hashtable immutability

假设我们有一个这样的自定义节点类:

class Node:
    def __init__(self, val, next, random):
        self.val = val
        self.next = next
        self.random = random

节点对象可以用作字典的键吗?我的理解是,对象必须是不可变的且可哈希化的,才有资格用作字典键,因为可变对象会导致哈希值变化,但该对象是可变的,因此不应用作键。可以将自定义可变类用作字典的键吗?答案似乎是肯定的,所以适当的问题是如何?

1 个答案:

答案 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

请注意,如果节点的任何属性发生更改,则它基本上会变成其他节点,并且很可能会导致产生不同的哈希值。我说的可能性最大,因为两个不同的节点最终可能具有相同的哈希值,所以这种现象称为哈希冲突。上面引用的链接具有相同的更多信息。