Search code examples
pythonif-statementparentheses

Python - Why these parentheses in if-statement alters the real condition?


I was doing a leetcode question while I had the following python code:

pairs = [(1, 3)]
addend = 3
sum = 4
if ((addend, sum - addend) or (sum - addend, addend)) in pairs:
    print("Pair exists")

The expected output when I ran this code should be

Pair exists

But instead this prints nothing, which I assume means ((addend, sum - addend) or (sum - addend, addend)) evaluates to False.

Then I removed the outer parentheses and made it

if (addend, sum - addend) or (sum - addend, addend) in pairs:
        print("Pair exists")

This gave me the right output.

My second guess was this pair of redundant parentheses actually calculates ((addend, sum - addend) or (sum - addend, addend)), so I put ((1, 3) or (3, 1)) in the Python3.7 console directly and that's the output

>>> ((1, 3) or (3, 1))
(1, 3)

But still this won't make sense since (1, 3) is indeed in pairs.

Could anybody explain why putting these parentheses invalidates the statement?


Solution

  • The result of a Python or expression is the first operand that is truthy, or False if neither is.

    The first expression you tried is

    ((addend, sum - addend) or (sum - addend, addend)) in pairs
    

    It can be evaluated as

    ((3, 1) or (1, 3)) in pairs
    

    Since both operands to the or expression in parentheses are non-empty tuples, the expression evaluates to

    (3, 1) in pairs
    

    The result is understandably false.

    If you strip off the parentheses, you run into the fact that or has lower precedence than in. So

    (addend, sum - addend) or (sum - addend, addend) in pairs
    

    is the same as

    (3, 1) or ((1, 3) in pairs)
    

    Again, both operands are truthy, so the expression evaluates to (3, 1) regardless of whether pairs contains anything.

    What you were probably trying to express is

    (addend, sum - addend) in pairs or (sum - addend, addend) in pairs