什么是Python字典的__hash__和__eq__评估的顺序?

时间:2016-06-29 16:19:05

标签: python dictionary hashable

我试图理解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&#39,或者抛出错误,取决于内部实施)。在这两种情况下,当它永远不能正确地等同时,它如何能够找到正确的钥匙?键(因为 eq 返回False)。

我在哈希上看到的所有文档总是提到哈希 eq ,从不 cmp ne < / strong>等,这让我觉得这两个是唯一在这种情况下发挥作用的人。

1 个答案:

答案 0 :(得分:5)

您用作dict键的任何内容都必须满足SELECT COUNT(UserId) AS Registrations ,SUM(CASE WHEN StripeCustomerId IS NOT NULL THEN 1 ELSE 0 END) AS Licenses ,CASE WHEN SUM(CASE WHEN StripeCustomerId IS NOT NULL THEN 1 ELSE 0 END) = 0 THEN 0 ELSE COUNT(UserId) / SUM(CASE WHEN StripeCustomerId IS NOT NULL THEN 1 ELSE 0 END) END AS [Percent] FROM Users WHERE DATEDIFF(hour, FirstContact, DateStamp) <= '12' 的不变量。 (我本来会说bool(x == x) is True,但是有一些合理的对象,它们甚至不是布尔值。)

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

==包括(x == x) is not Truefloat('nan')的合理对象。