Can we compare one value with multiple values using 'or'?

Question

When comparing one value with multiple values, can we just separate each value with or?

Answer

No, when comparing one value with many other values, or cannot be used to check, for instance, if “a value equals some value or another value or another value.” Each side of the or must be a valid expression on their own, so this would not work.

Example

# This would not compare value with 10, 11, 12.
if (value == 10 or 11 or 12):
  print("Fourth quarter")

# Instead, each comparison must be separate and 
# valid on their own on each side of each "or".
if (value == 10 or value == 11 or value == 12):
  print("Fourth quarter")
21 Likes

it will not work as expected, fine. but how does it work?

does it just compare the first number and leave or doesn’t compare at all or is there any default result ?

or ( as well as and) does not necessarily return True or False.

or goes through its operands right to left, and returns the value of first one that has a “truth value” of True. If none of them have a truth value of Truth value of True, it returns the value of the last operand.

If all of the operands are True or False, or expressions that resolve to True or False, it will work as you expect.

But if the operands are other objects (ints in the example), Python goes by the rules:

  • The truth value of False, 0, any empty container or any expression that evaluates to one of those objects is False.
  • The truth value of everything else is True.
x = 1 or 2

y = 0 or []

z = 3 > 2 or 5 < 10
print(x)
print(y)
print(z)

# Output
1      # first True
[]     # last value, as both have a truth value of False
True   # Expression evaluates to true

(and works in a similar way: it returns the value of the first object that has a truth value of False; otherwise, it returns the value of the last operand tested.)

4 Likes

To more directly answer the OP:

value = 10
if (value == 10 or 11 or 12):
 print("Fourth quarter")
 
value = 3.14
if (value == 10 or 11 or 12):
 print("Fourth quarter")

# Output:
Fourth quarter
Fourth quarter

The expression (10 or 11 or 12) will always return 10, according to what I wrote above. Since 10 has a truth value of True, the if clause will always pass, no matter the value of the variablevalue.

2 Likes

Is the precedence of the comparison operator(==) lesser than ‘or’ operator? As you have said that the logical result is prioritized more than the result of comparison. Does python have a precedence following nature?

== is of higher precedence than and, and and is higher than or, according to the docs.

In the above examples, value == 10 is evaluated first, returning True in one case, and False in the next.
That leaves:

True or 11 or 12 # case 1
False or 11 or 12 # case 2

Let’s evaluate those:

print(True or 11 or 12)
print(False or 11 or 12)

# Output:
True   # First True
11     # First True

Both of these have a truth value of True, so both if blocks are triggered.

Python definitely has an order of operator precedence, which I linked to above. Note that in that table, precedence is from least to greatest (i.e., least on top). Expressions containing operators of the same precedence are evaluated left to right.

yes but isn’t [] an empty container? therefore shouldn’t it be a False? so why it is printed?

Are you referring to this (from above)?

x = 1 or 2

y = 0 or []

z = 3 > 2 or 5 < 10
print(x)
print(y)
print(z)

# Output
1      # first True
[]     # last value, as both have a truth value of False
True   # Expression evaluates to true

Remember that Python prints, in the case of or, the first value (object) that that has a boolean (“truthy”) value of True, and the second value if both have a boolean value of False. In this case, [] is the second value (object). (And, likewise, and returns first False or second True object.)

The point is that, unlike other comparison operators, which return either True or False or raise a TypeError if the values cannot be compared, and and or return the value of one of their operands. If those operands are boolean expressions that return True or False, the behavior is what you expect; if not, you will see one of the operands themselves (i.e., one of the objects) returned.

x = 'abc'
y = []

print(bool(x))
print(bool(y))

print(x or y)
print(x and y)

print(x >= y)

Output:

True
False
abc  # first True
[]  # first False
Traceback (most recent call last):
  File "C:\Users\path\totest.py", line 9, in <module>
    print(x >= y)
TypeError: '>=' not supported between instances of 'str' and 'list'
1 Like

Even though 3.14 is not equal to 10, python will consider it true?

patrickd314 covers this in his answer? 11 and 12 are not compared to anything, as such, python will evaluate if they are truthy values. Truthy means a value which is considered true. Positive integers are considered true.

Which is simple to demonstrate:

if 11:
   print('11 is considered a truthy value')

How can we understand precedence in complex mixes of and or ==

print(0 == False and 3 or 4 and 7 or [ ] and 0 ) # 3

print(0 or False and 3 or 4 and 7 or [ ] and 0 ) # 7
2 Likes

In case you’d like to check a variable against multiple values, you can use sets.
So, in a setting like the original question, we’d have:

if (value in {10, 11, 12}:
  print("Fourth quarter")

Since, AND has higher precedence than OR. All the AND’s expression will be solved first, using the logic explained by @patrickd314.

Then, when only OR is remaining in the expression it becomes the same case also explained by @patrickd314

Hi, I know we’re discussing logical and relational operators so it makes sense to see to use OR but I agree with “tajaddini” that the best way to check if a value is 10 or 11 or 12 is to use IN rather than OR
e.g. if value in [10, 11, 12]: …