如何使用__contains__ /"in"关键字在Python列表中搜索对象?

Nat*_*Coy 2 python contains list

我想列出我定义的对象列表,然后使用in关键字(调用__contains__)来确定Python列表中是否存在所述对象.

这是一个带注释的最小例子:

>>> class Foo(object):
...     def __init__(self, name):
...             self.name = name
...     def __contains__(self, item):
...             return self.name == item
... 
>>> list_of_objects = [Foo("bar"), Foo("baz"), Foo("quux")]
>>> # I want to see if "bar" is in this list of Foo() objects
>>> Foo("bar") in list_of_objects
False      # <-- I want this to be True
Run Code Online (Sandbox Code Playgroud)

in关键字是否应该迭代Python列表并使用该__contains__方法来确定对象的存在?

如果调用列表index()功能也可以使用额外的荣誉.

更新

感谢@ user2357112,看起来答案是实现等价运算符__eq__.Foo在上一个示例中将以下位添加到类中可以解决我遇到的问题.

>>> class Foo(object):
...     def __init__(self, name):
...             self.name = name
...     def __eq__(self, other):
...             return other.name == self.name
>>> list_of_objects = [Foo("bar"), Foo("baz"), Foo("quux")]
>>> Foo("bar") in list_of_objects
True
Run Code Online (Sandbox Code Playgroud)

ber*_*eal 5

__contains__是在容器上调用的方法,而不是在元素上调用的方法.你需要实现__eq__:

class Foo(object):
    def __init__(self, name):
        self.name = name

    def __eq__(self, other):
        if isinstance(other, Foo):
            return other.name == self.name
        return self.name == other
Run Code Online (Sandbox Code Playgroud)

如果您要存储Foo在其他容器(例如set)中,请记住实现__hash__.

  • 当你在它时,你也应该定义`__ne__`,或`==`和`!=`将彼此不一致.如果对象是可变的,那么你应该设置`__hash__ = None`而不是定义`__hash__`来使对象不可用.无论你是否计划对这些对象使用`!=`,sets或dicts,都应该处理这些事情,因为现在让它们变得比试图调试以后发生的疯狂事情要容易得多,如果你忘了你没做的话.处理任何一个. (4认同)