-1

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?

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
Hang
  • 355
  • 3
  • 19
  • `if (addend, sum - addend) in pairs or (sum - addend, addend) in pairs:` – Stephen Rauch Feb 07 '19 at 03:45
  • The parentheses are *not* redundant`(addend, sum-addend) or (sum-addend,addend)` -> `(3, 1)` which is not in `pairs` – juanpa.arrivillaga Feb 07 '19 at 03:46
  • https://docs.python.org/3/reference/expressions.html#operator-precedence – Stephen Rauch Feb 07 '19 at 03:46
  • I would really love to answer but someone marked it as duplicate, so here it is in a comment: U9-Forward is right, you should use `any`, or use a double `or`. However if you were curious as to why your first method wasn't working, it was because you had `((addend, sum-addend) or (sum-addend,addend))`, which equates to `((3,1) or (1,3))`, and since, as you saw, only the first in this pair is left after using `or`, you are left with `(3,1)`, which does not appear in `pairs` because `pairs = [(1,3)]`, hence no output. The most curious thing here is how or is behaving in the brackets. Very unusual – Recessive Feb 07 '19 at 03:55
  • 1
    @Recessive Thanks a lot for your comment. Yea, "how or is behaving in the brackets" makes this question appear. Really like funny magic! – Hang Feb 07 '19 at 03:58

2 Answers2

2

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
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • Thanks Mad Physicist! After reading all the above answers and comments I was still confused about why stripping off the parentheses would make the statement True, until you said "or has lower precedence than in" and '''if (3,1)''' would evaluate to True. That's really helpful! – Hang Feb 07 '19 at 04:20
  • @Hang. Glad it helped you. Some things Python does are a bit unusual, especially for a beginner, so I try to express what went into the aha moment I had when I first understood the topic. Good luck to you in your endeavors. – Mad Physicist Feb 07 '19 at 04:48
  • 1
    Yea definitely, and you got right to the point! Appreciate it again and best wishes for you too in the new year! – Hang Feb 07 '19 at 14:39
1

You should use any:

if any(i in pairs for i in [(addend, sum-addend),(sum-addend,addend)]):

Or use:

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

You can't use or because or just picks an element which is not indeed that that's the element in pairs, so use the above codes.

U13-Forward
  • 69,221
  • 14
  • 89
  • 114