2

I've come across a weirdness in Python I don't understand:

>>> x = 1
>>> L = [1, 2]
>>> u = True
>>> x in L == u
False
>>> (x in L) == u
True
>>> x in (L == u)
TypeError: argument of type 'bool' is not iterable.

Can someone explain how Python processes x in L == u and (x in l) == u?

Thank you.

Python version: 3.9.12

The Thonnu
  • 3,578
  • 2
  • 8
  • 30
  • [Operator Precedence](https://docs.python.org/3/reference/expressions.html#operator-precedence) knows all. – tdelaney Sep 30 '22 at 16:50
  • Okay, a link on Operator Precedence tells all.... – tdelaney Sep 30 '22 at 17:46
  • 1
    also, in this case, `in` and `==` are both comparison operators (which is a bit counterintuitive to me that `in` is) [so they are chained](https://docs.python.org/3/reference/expressions.html#comparisons), and `x in L == u` is the same as `x in L and L == u` – juanpa.arrivillaga Sep 30 '22 at 17:48

1 Answers1

2

in and == have the same precedence, but looking at the python language Comparisons section, these operations are chained so that an expression such as a < b < c work in the mathematical sense, unlike languages such as C.

Formally, if a, b, c, …, y, z are expressions and op1, op2, …, opN are comparison operators, then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z, except that each expression is evaluated at most once.

Thus x in L == u is equivalent to x in L and L == u. Python does not use the result of x in L in the next comparison. In fact, if x is not in L, python would short-circuit immediately and would not even execute the == comparison.

When you group with parenthesis, these operations are no longer chained. x in L is evaluated as an expression and its result is used in the next comparison.

tdelaney
  • 73,364
  • 6
  • 83
  • 116