-1

I'm searching a list to see if it contains one of several elements within it using Python's "in" statement. I'm finding issues however. Here's a MWE:

print (1 or 2 or 3) in [1, 2, 3]

print (1 or 2 or 3) in [2, 3]

Both statements should return True, but the actual output is:

True
False

It seems that what the code is actually doing is simply searching for the number 1 in the list, rather than 1, 2, or 3. Why is it doing this, and how can I modify the code to behave correctly?

mknote
  • 157
  • 1
  • 3
  • 12
  • 2
    `(1 or 2 or 3)` is just `1`, yes. You can see this with `print (1 or 2 or 3)`. Canonical: https://stackoverflow.com/q/15112125/3001761 – jonrsharpe Jun 01 '21 at 20:09
  • 3
    `(1 or 2 or 3)` is an expression by itself, which evaluates to `1`, *not* an extension of the `in` operator. In `a in b`, you evaluate `a`, then evaluate `b`, *then* call `b.__contains__(a)`. – chepner Jun 01 '21 at 20:09

1 Answers1

2

(1 or 2 or 3) in [1, 2, 3] is equivalent to

[1, 2, 3].__contains__(1 or 2 or 3)

not

[1,2,3].__contains__(1) or [1,2,3].__contains__(2) or [1,2,3].__contains__(3)

. The expression 1 or 2 or 3 is evaluated to 1 before __contains__ actually gets called. x or y evaluates to x if bool(x) is true, otherwise it evaluates to y. (Since or is not a regular operator or function, y is only evaluated if bool(x) is false.)

To do what you want, you can use the any function:

print(any(x in [1,2,3] for x in (1, 2, 3)))
chepner
  • 497,756
  • 71
  • 530
  • 681
  • Thank you, this is exactly what I needed in a nice, compact form. It's strange that they implemented it this way, but I'm guessing there's a good reason for that. Many thanks. – mknote Jun 01 '21 at 20:31
  • It's not that strange. It would be exceedingly difficult to define an arbitrary combination of `or`, `and`, and `in` keywords into some sort of embedded query language. `in` is very simple: it takes two arguments: the container, and the thing you want to check is contained. – chepner Jun 01 '21 at 20:36
  • Don't expect natural-language semantics from a programming language. – chepner Jun 01 '21 at 20:37
  • I thought that better use of natural-language semantics was one of the benefits of Python, although I suppose that's only relative to other languages. Naturally there's a limit to how much that applies. – mknote Jun 01 '21 at 20:44
  • It's *more* natural, but that extends more to the use of words over symbols where possible (`or` instead of `||`, etc). Think about what the individual expression `(1 or 2 or 3)` would have to actually *evaluate* to in order to make `(a or b or c) in d` equivalent to `a in d or b in d or c in d`, while maintaining things like `if a or b or c: `. `or` is not a regular function, or you couldn't handle short-circuiting. – chepner Jun 01 '21 at 20:49