How the 'in' operator works in Python

4

Could someone explain to me the logic of the 'in' operator of python? I've done some testing on idle and I still can not figure out how it works.

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

In the above case, because it would find 2 or 10 in the range of 1 to 5, but it does not find 10 or 2 in the range of 1 to 5.

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

How did you find 10 and 2 in the range of 1 to 9?

I'm sure I'm getting this operator wrong.

    
asked by anonymous 20.07.2017 / 03:15

1 answer

8

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

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

Does not check if the numbers 2 and 10 are in range(1, 6) . What happens is that Python will first parse the logical expression 2 or 10 and verify that the result of this expression belongs to range(1, 6) . Python interprets any integer value other than zero as true and only zero as false. So making 2 or 10 , for Python, is the same as True or True . In this case, since the logical operator is or and the first operand is true, it will not import the value of the second, so the value of the second is returned, so Python will check only if 2 is in range(1, 6) , returning true. This behavior of returning a value before parsing the entire logical expression is called a short circuit.

Logical operations in Python 2.7 (More on how Python evaluates logical expression)

Then, in the other case, (10 or 2) in range(1,6) , the same logic occurs. The number 10 will be parsed as true and being the or operator, the logical expression short circuit again occurs, returning as a result the own value 10. Thus, Python will check if 10 in range(1, 6) , returning false. p>

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, from or to and . Being and , the logical expression short circuit will not occur when the first operand is true, then the second operand, 2, will be parsed and returned. So, 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 at Ideone .

Short circuit occurs when:

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

If in the or operator the first operand is false, the value of the second operand is returned. If in the and operator 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 need to do:

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

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

That is, the code below results in False , since 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 , since all elements belong to range(1, 6) :

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

See working at Ideone .

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

>>> B.issubset(A)

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

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

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

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

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

  

See working at Ideone .

    
20.07.2017 / 03:22