How exactly do or/and operators in Python behave?

64 Views Asked by At

How exactly does Python evaluate statements connected by multiple and/or operators?

When I run the following statement in Python:

[1] or [] and (1,) or ()

the output is [1].

But for the below statement,

[] or [1] and (1,) or ()

the output is (1,).

I am confused. What causes the difference in outputs for both statements? What is the order of evaluation here?

3

There are 3 best solutions below

0
Manvi On

In "or" operator when one of the condition is true then it returns "True" if the both conditions are false it returns "False"

So with your first condition: "1 or [] and (1,) or ()"

When you separate the conditions one-by-one as:
**[1] or []**
It returns true as one of the condition is true.

with second condition in this 
**[] and (1,)**
It will return false as one condition is true but it uses and operator.

with the third condition in this
**(1,) or ()**
It will return true as one of the condition is true.

If you put all the conditions together:
**"[1] or [] and (1,) or ()"**
We can expand it like 
**"T or F and T"**
It will return **"True"** as it satisfied the **or** operator.

In "and" operator it returns "True" when both the conditions are true if one of the conditions is false then it returns "False"

Same goes with your second condition [] or 1 and (1,) or ()

Note: T for "True" F for "False"

For reference you can go through this link

1
Tim Peters On

They aren't evaluated strictly left-to-right: and has higher precedence (binds more tightly) than or. So your examples are evaluated like so:

[1] or ([] and (1,)) or ()

[1] is "truthy", so the expression in parentheses isn't evaluated at all. [1] is the result of the first or. Similarly for the second or.

The other:

[] or ([1] and (1,)) or ()

[] is "falsey", so the expression in parentheses is evaluated. [1] is truthy, so and goes on evaluate (1,), which is also truthy, and so is and's result. Because (1,) is truthy, the second part of the second or isn't evaluated, and (1,) is the final result.

Note that "isn't evaluated" means what it says. For example,

>>> [] or [1] and (1,) or 1/0
(1,)

We didn't get a divide-by-zero exception because the 1/0 part is never evaluated - or's left operand already determined the final outcome.

0
Murad Khalilov On

[] and (1,): The and operator first evaluates [], which is considered False (an empty list). According to short-circuit evaluation, since the left operand is False, Python doesn't evaluate the right operand (1,). Instead, it returns [].

[1] or []: Since the left operand [1] is considered True (a non-empty list), Python short-circuits the or operator and returns [1].

So, overall, the expression [1] or [] and (1,) or () evaluates to [1].

print([1] or [] and (1,) or ())  # Output: [1]

However, in the other hand, the expression involves both and and or operators. To correctly evaluate this expression, we need to understand the precedence of these operators and how Python evaluates expressions involving them.

In Python, the and operator has higher precedence than the or operator. When multiple 'and' and 'or' operators are present in an expression, Python follows a left-to-right evaluation order.

Let's break down the expression step by step:

[1] and (1,): Since both [1] and (1,) are considered True (non-empty list and non-empty tuple respectively), the and operation returns the second operand, which is (1,). [] or (1,): Since the left operand [] is considered False (empty list), Python evaluates the right operand (1,). The or operation returns the second operand, which is (1,). (1,) or (): Both (1,) and () are considered True (non-empty tuple and non-empty tuple respectively). The or operation short-circuits and returns the first operand, which is (1,). So, overall, the expression evaluates to (1,).

print([] or [1] and (1,) or ())  # Output: (1,)