5

我试图了解 Python 字典必须在内部做什么才能找到一个键。在我看来,哈希将首先被评估,如果发生冲突,Python 将遍历键,直到找到eq返回 True 的键。这让我想知道为什么以下代码有效(测试代码仅用于理解内部):

class MyClass(object):
    def __eq__(self, other):
        return False

    def __hash__(self):
        return 42

if __name__=='__main__':

    o1 = MyClass()
    o2 = MyClass()
    d = {o1: 'o1', o2: 'o2'}
    assert(o1 in d)      # 1
    assert(d[o1]=='o1')  # 2
    assert(o2 in d)      # 3
    assert(d[o2]=='o2')  # 4

字典不应该找不到正确的键(在#2和#4两种情况下都返回'o1'或'o2',或者抛出错误,取决于内部实现)。在这两种情况下,它如何能够在正确的键上着陆,而它永远不能正确地“等同”键(因为eq返回 False)。

我在散列方面看到的所有文档总是一起提到hasheq,从不cmpne等,这让我认为这两个是唯一在这种情况下发挥作用的文档。

4

1 回答 1

5

您用作 dict 键的任何内容都必须满足不变量bool(x == x) is True. (我会说x == x,但有一些合理的对象甚至不是布尔值。)

dict 假设这将成立,因此它用于检查密钥相等性的例程实际上在使用之前首先检查对象身份==。这个初步检查是一个实现细节;你不应该依赖它发生或不发生。

(x == x) is not True包括float('nan')和的合理对象numpy.array([1, 2])

于 2016-06-29T16:24:51.023 回答