qntm
qntm

Reputation: 4417

How can I test whether an element is in a list using identity instead of equality?

In Python, I can test whether an element is in a list like so:

elem = 56
long_list = ["foo", "bar", asdf, 56, False]
print(elem in long_list) # "True"

This is equivalent to:

elem = 56
long_list = ["foo", "bar", asdf, 56, False]

result = False
for candidate in long_list:
    if elem == candidate:
        result = True
        break
print(result) # "True"

Notice elem == candidate, which tests for equality.

What I want to do is test for identity using elem is candidate instead. What is the easiest way to do this in Python?

I tried Google, but the words "is" and "in" are unfortunately too common. I also tried

print(elem is in long_list)

but this gave me a syntax error.

Upvotes: 3

Views: 416

Answers (3)

alexis
alexis

Reputation: 50220

If the elements being compared implement __eq__ in terms of is, you can simply use elem in long_list and it will be invoked for you automatically. So this should work with your objects:

def __eq__(self, x):
    return self is x

To keep things simple, here's a little demo that overloads equality to be str.startswith (of the second operand) instead of identity.

>>> class permissive(str):
        def __eq__(self, x):
            return self.startswith(x)

>>> mylist = map(permissive, [ "hip", "hop" ])
>>> "hi" in mylist
True

Of course you'll get the same super-strict behavior when comparing your objects for equality in other contexts. If your goal is just to find a specific object in a list, perhaps you should define __hash__ instead and store them in a dictionary?

Upvotes: 0

georg
georg

Reputation: 215009

I might be misunderstanding the question, but if an object doesn't implement __eq__, in and == default to identity comparison, which is what you want.

class Foo:
    pass

a = Foo()
b = Foo()
c = Foo()

print (a in [a,b]) # True 
print (c in [a,b]) # False

Upvotes: 2

Pavel Anossov
Pavel Anossov

Reputation: 62928

Use any with a generator expression:

any(elem is candidate for candidate in long_list)

Upvotes: 4

Related Questions