Python 'in' keyword in expression vs. in f

2020-02-08 18:50发布

问题:

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.

回答1:

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, define y.__contains__().
  • To change for x in y, define y.__iter__().


回答2:

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.



回答3:

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.