How the Python 'in' operator works

Asked

Viewed 1,269 times

5

Could someone explain me the logic of python’s 'in' operator? I did some tests on Idle and still can’t understand how it works.

>>> (2 or 10) in range(1,6)
True
>>> (10 or 2) in range(1,6)
False

In the above case, because he would find 2 or 10 in the range from 1 to 5, but not 10 or 2 in the range from 1 to 5.

>>> (10 and 2) in [1,2,3,4,5,6,7,8,9]
True

As such, found 10 and 2 in the range 1 to 9?

I’m sure I’ve got the wrong operator.

1 answer

9

The problem is not with the operator in, but on the logical operator or and and that you used. Do:

>>> (2 or 10) in range(1,6)

Do not check if the numbers 2 and 10 are in the range(1, 6). What happens is that Python will first parse the logical expression 2 or 10 and check that the output of this expression belongs to range(1, 6). Python interprets any non-zero integer value as true and only zero as false. So do 2 or 10, for Python, it is the same as True or True. In this case, as the logical operator is the or and the first operand is true, no matter the value of the second, then the value of the first, 2 is returned. So Python will check only if 2 is in range(1, 6), returning true. This behavior of returning a value before analyzing the entire logic expression is called short-circuit.

Logic operations in Python 2.7 (More about how Python evaluates logical expression)

So in the other case, (10 or 2) in range(1,6), the same logic occurs. The number 10 will be analyzed as true and the operator or, occurs again the short-circuit of the logical expression, returning as a result the appropriate value 10. Thus, Python will verify if 10 in range(1, 6), returning false.

In the third expression:

>>> (10 and 2) in [1,2,3,4,5,6,7,8,9]

The only thing that changes is the logical operator, of or for and. Being and, the logic expression will not short-circuit when the first operand is true, then the second operand, 2, will be analyzed and returned. Thus, the return of 10 and 2 will be 2 and Python will check if it is in [1,2,3,4,5,6,7,8,9], returning true.

Just take the test:

# (2 or 10) ocorre o curto-circuito, retornando o primeiro operando: 2
print(2 or 10)

# (10 or 2) ocorre o curto-circuito, retornando o primeiro operando: 10
print(10 or 2)

# (2 and 10) não ocorre o curto-circuito, retornando o segundo operando: 10
print(2 and 10)

# (10 and 2) não ocorre o curto-circuito, retornando o segundo operando: 2
print(10 and 2)

See working on Ideone.


The short circuit occurs when:

  • On the operator or, the first operand is true, for True or X will always be true independent of X;
  • On the operator and, the first operand is false, for False and X will always be false regardless of X;

If on the operator or the first operand is false, the value of the second operand is returned. If the operator and the first operand is true, the value of the second operand is returned.


To check if a list of numbers is contained in another list with Python, you will need to do:

>>> all(x in range(1, 6) for x in [2, 10])

In this case, all elements of [2, 10] shall be covered by x and checked, one by one, if they belong to the set range(1, 6). If at least one does not belong, the function all return false. Return true if all elements belong to the other set.

That is, the code below results in False, for 10 does not belong to range(1, 6):

>>> all(x in range(1, 6) for x in [2, 10])

But the code below returns True, because all the elements belong to range(1, 6):

>>> all(x in range(1, 6) for x in [2, 4])

See working on Ideone.

Another way is to work with mathematical sets. To know if the set B is a subset of the set A, in Python, just do:

>>> B.issubset(A)

This way, to know if [2, 10] is a subset of range(1, 6), do:

>>> A = set(range(1, 6))
>>> B = set([2, 10])
>>> B.issubset(A)
False

Returns false, because 10 does not belong to the set A. However, if you test with the set [2, 3]:

>>> A = set(range(1, 6))
>>> B = set([2, 3])
>>> B.issubset(A)
True

For the whole {2, 3} is a subset of range(1, 6)).

See working on Ideone.

  • I thought very good his explanation, I was here breaking my head to know why [1,2,3] in [1,2,3] returned False. Still, I didn’t find it very user friendly for beginners. But I guess I get used to it. Thank you so much.

  • Actually it is, but you’re probably still misinterpreting at first glance. This will change over time and you will see that such a notation makes sense, as doing [1,2,3] in [1,2,3] checks if the first entire list belongs to the second. Verification is not done element by element.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.