自定义类对象和“in”集合运算符

我正在使用 Python 3.6。假设我试图保留一组唯一的元组。我知道我可以使用tuple in set并取回正确的结果(该集合是否包含元组)。

s = set()
t1 = (1, 2)
t2 = (1, 2)
s.add(t1)
print(t2 in s) # True -- Great!

现在,假设我有一个包含元组的自定义类。我想将自定义类对象的唯一性定义为元组的唯一性。我做了以下事情:

class TupleWrapper(object):

    def __init__(self, t):
        self.t = t # tuple

    def __hash__(self):
        return hash(self.t)


s = set()
t1 = TupleWrapper((1, 2))
s.add(t1)
t2 = TupleWrapper((1, 2))
print(t2 in s) # False -- WHY?

我编写了自己的__hash__()方法来对元组进行哈希处理。那么为什么TupleWrapper没有发现具有相同元组的两个对象在set. 我需要覆盖另一个方法吗?

回答

您需要实现__eq__TupleWrapper也是如此。

def __eq__(self, other):
    if isinstance(other, TupleWrapper):
        return self.t == other.t
    return NotImplemented

否则,当检查对象是否已经在集合中时,它将默认为身份比较,这只是is(即,t1 is t2id(t1) == id(t2))。

更多细节:松散地说,在插入时,set(和dict)首先使用散列值来确定哪个桶中的东西。然后,在那个桶中,它使用==,在散列冲突的情况下用来检查该对象是否已经存在那里。

散列文档在这里

  • @stackoverflowuser2010 for starters, https://docs.python.org/3/reference/datamodel.html#object.__hash__
  • @stackoverflowuser2010: `__eq__` is the overload hook for `==` equality comparisons.
  • Thank you. How would I know that `thing in set` would call `thing.__eq__(other)`? Is it documented clearly somewhere?

以上是自定义类对象和“in”集合运算符的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>