Reputation: 4417
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
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
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
Reputation: 62928
Use any
with a generator expression:
any(elem is candidate for candidate in long_list)
Upvotes: 4