首页 > 解决方案 > 自定义类对象和“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__()散列元组的方法。那么为什么在 tuple 中没有发现相同元组的两个TupleWrapper对象是相同的set呢?我需要覆盖另一种方法吗?

标签: python

解决方案


您还需要实施__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)首先使用哈希值来确定对象在哪个桶中。然后,在那个桶中,它用于==检查,在哈希冲突的情况下,如果该对象已经存在那里。

哈希文档在这里


推荐阅读