14

I understand what the in operator does in this code:

some_list = [1, 2, 3, 4, 5]
print(2 in some_list)

I also do understand that i will take on each value of the list in this code:

for i in [1, 2, 3, 4, 5]:
    print(i)

I am curious if the in operator used in the for loop is the same as the in operator used in the first code.

cxw
  • 16,685
  • 2
  • 45
  • 81
Novice
  • 575
  • 2
  • 7
  • 16

3 Answers3

31

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

cxw
  • 16,685
  • 2
  • 45
  • 81
  • 2
    upvote because you can change the behavior of the first kind of `in` by defining `__contains__` – taylor swift Jul 05 '16 at 13:19
  • The way it is worded implies to me that operator and keywords are seperate things although I would argue that it's nearly the same or that operators are also keyword. – syntonym Jul 05 '16 at 13:23
  • @syntonym fixed - thanks :) – cxw Jul 05 '16 at 13:24
  • I found out that you could do `for...else`, so I felt that the `in` used in the `for` loop is essentially the same `in` as the one in the `print(2 in some_list)` example. – Novice Jul 05 '16 at 13:38
  • @Novice yes, `for`/`else` is a common source of confusion. I recently discovered [this blog post](http://python-notes.curiousefficiency.org/en/latest/python_concepts/break_else.html#what-possible-use-is-the-current-behaviour) that I found helpful in that regard, and I hope my answer was useful to you! – cxw Jul 05 '16 at 13:43
  • I was guessing that `for x in some_list` would assign each element of `some_list` to `x` and `x in some_list` would act as the condition for the loop. – Novice Jul 05 '16 at 13:45
  • 2
    @Novice that was a very understandable guess :) . The difference is subtle but real. For example, `__contains__` is not called by the `for` loop. Anyway, happy coding! – cxw Jul 05 '16 at 14:00
0

No, it is not the same. The in test like in your first example is a test for membership and returns a truth value. This in might be thought of as the sequential analogue of == or is (depending on how __contains__ is implemented).

The in in your second example is part of the iteration grammar; it temporarily binds your selected variable i to each item in the iterable. This in might be thought of as the sequential analogue of =, the assignment operator.

taylor swift
  • 2,039
  • 1
  • 15
  • 29
0

No, although they both use the same word they do different things. in is in both cases a syntax structure, e.g. it is not a name of a object and can't be changed. You can see here and here the syntactic definition of each one. As you can see the names are hardcoded and have no relationship.

syntonym
  • 7,134
  • 2
  • 32
  • 45