Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to search objects in Python List using __contains__ / "in" keyword?

I would like to make a list of objects which I define, then use the in keyword (which calls __contains__) to determine if said object exists in the Python list.

Here is a minimal example with comments:

>>> 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

Shouldn't the in keyword iterate over the Python list and use the __contains__ method to determine existence of the object?

Extra kudos if calls to lists index() function are also operational.

Update

Thanks to @user2357112, Looks like the answer is implementing the equivalence operator __eq__. Adding the following bit to the Foo class in the previous example fixes the issues I was having.

>>> 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
like image 559
Nathan McCoy Avatar asked Oct 17 '25 14:10

Nathan McCoy


1 Answers

__contains__ is the method that's called on the container, not on the elements. You need to implement __eq__ instead:

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

If you are going to store Foo in other containers (like set), remember to implement __hash__.

like image 139
bereal Avatar answered Oct 20 '25 03:10

bereal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!