Does the 'in' operator use "==" or "is" for comparisons?
Asked Answered
T

2

8

In a Python expression like str in [str1, str2, str3] or 1 in [1, 2, 3], does the in operator use == or is to compare the first object with the objects in the list?

Turenne answered 14/3, 2018 at 0:44 Comment(1)
F
12

It depends on the object how in is executed; it is not the in operator that makes the comparison, it is the object.__contains__ method that does the work.

For the Python standard container types (list, tuple, set, dict, etc.) both identity and equality are used. See the Membership test operations section of the Expressions reference documentation:

For container types such as list, tuple, set, frozenset, dict, or collections.deque, the expression x in y is equivalent to any(x is e or x == e for e in y).

is is faster to test for, and objects having the same identity implies they are also equal.

Custom types are free to implement whatever test they want to do in their __contains__ method.

Next, if no __contains__ method is defined, but there is a __iter__ method or a __getitem__ method, then an iterative search is preformed where the values produced are tested for both identity and equality again. See the above linked documentation for details; the documentation is not that explicit about the identity test but the implementation still uses identity because using it is a performance boost.

You can see this when you use float('nan'), which is never equal to itself or anything else:

>>> nan = float('nan')
>>> nan == nan
False
>>> nan is nan
True
>>> nan in [nan]  # tests for identity first
True
>>> nan in iter([nan])  # an iterator, only __iter__ is defined
True

float('nan') is an exception to the normal expectation that identity implies equality; see What is the rationale for all comparisons returning false for IEEE754 NaN values? for why that is.

Farina answered 14/3, 2018 at 0:51 Comment(2)
Your summary (saying "for [...] standard container types [...] equality is used") contradicts your quote from the docs. Membership tests for built-ins use both identity and value equality tests, testing identity first, then equality if the identity test fails.Vivisection
@ShadowRanger: yes, it's late and I should really just call it a night. Thanks for pointing that out.Farina
T
0

It seems to use ==. With the following test:

Python 2.7.14 (default, Mar  1 2018, 19:24:37)
$ str1 = 'a bc'
$ str1 is 'a bc' # returns False
$ str1 in ['a bc'] # returns True

Any links to official documentation about this would be appreciated! My Google-fu has failed me thus far.

Turenne answered 14/3, 2018 at 0:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.