Python 'in' keyword in expression vs. in for loop
They are the same concept but not the same operators.
In the print(2 in some_list)
example, in
is an operator that handles several different situations. The Python docs for the in
operator give the details, which I paraphrase as follows: x in y
calls y.__contains__(x)
if y
has a __contains__
member function. Otherwise, x in y
tries iterating through y.__iter__()
to find x
, or calls y.__getitem__(x)
if __iter__
doesn't exist. The complexity is to provide consistent membership testing for older code as well as newer code — __contains__
is what you want if you're implementing your own classes.
In the for
loop, in
is just a marker that separates the loop-index variable from whatever you're looping over. The Python docs for the for
loop discuss the semantics, which I paraphrase as follows: whatever comes after in
is evaluated at the beginning of a loop to provide an iterator. The loop body then runs for each element of the iterator (barring break
or other control-flow changes). The for
statement doesn't worry about __contains__
or __getitem__
.
Edit @Kelvin makes a good point: you can change the behaviour of in
with respect to your own new-style classes (class foo(object)
):
- To change
x in y
, definey.__contains__()
. - To change
for x in y
, definey.__iter__()
.