Logical Operators and Boolean Expressions
Short-circuit evaluation stops evaluating a logical expression once the result is already determined.
Why Evaluation Order Matters
A logical expression can contain more than one condition. Python evaluates those parts from left to right, but it does not always evaluate every part. When the result is already determined, Python stops. This behavior is called short-circuit evaluation.
The central rule is simple: and stops when the first part is False, while or stops when the first part is True.
Tracing a Logical Expression
Following an and expression
Trace the expression x >= 2 and (x/y) > 2 when x is less than 2.
Check the first part: Because x is less than 2, x >= 2 evaluates to False.
Apply the and rule: In an and expression, a False first part makes the entire expression False. Python therefore does not evaluate (x/y) > 2.
Check the consequence: Since the division is not attempted, a zero value for y does not cause a ZeroDivisionError in this case.
The expression is False, and the second part is skipped.
What do you think happens?
What happens when x is less than 2 and y is zero in x >= 2 and (x/y) > 2?
Reveal answer
Answer: Python stops after the first part and the expression is False.
The first part is False. That already determines the result of an and expression, so Python never evaluates the division.
The Two Short-Circuit Rules
| Operator | First part | What Python does | Reason |
|---|---|---|---|
| and | False | Stops and does not evaluate the later part | The entire and expression must be False |
| and | True | Evaluates the later part | The later part is needed to determine the result |
| or | True | Stops and does not evaluate the later part | The entire or expression must be True |
| or | False | Evaluates the later part | The later part is needed to determine the result |
The two operators use opposite stopping conditions. With and, the first part must be False to prevent the later part from running. With or, the first part must be True to prevent the later part from running. The operator and the guard condition must therefore be chosen together.
Using the Guardian Pattern
The guardian pattern places a safe guard condition before a risky operation in a logical expression. If the guard makes the first part False in an and expression, Python stops before evaluating the risky operation.
In x >= 2 and (x/y) > 2, x >= 2 is the guard and (x/y) > 2 is the risky operation. When x is less than 2, the guard is False. The and expression is then already False, so Python never attempts the division. If the guard is True, Python continues and evaluates the second part.
The same pattern can protect a list access. The guard len(my_list) > 0 ensures that my_list[0] is accessed only when the list is not empty. When the list is empty, the guard is False and the list access is skipped, preventing an IndexError.
Mistakes Beginners Make
Assuming Python always evaluates both parts of a logical expression
When x >= 2 is False, the and result is already determined, so Python skips the division.
Fix:
Trace the first part first and ask whether it already determines the result.Reversing the short-circuit rules
The stopping conditions are opposite: and stops on False, while or stops on True.
Fix:
Remember that a False first part settles and, and a True first part settles or.Putting the risky operation before the guard
Python evaluates from left to right, so a later guard cannot prevent an earlier operation from running.
Fix:
Place the safe guard first.Choosing an operator without considering the guard's required result
An and expression needs a False first part to skip its second part, while an or expression needs a True first part.
Fix:
Choose the operator and guard condition together.
Practice the Trace
For each situation, identify whether Python evaluates the later part of the expression. Explain your answer using the words guard, short-circuit, and result already determined.
Hints
- For and, ask whether the first part is False.
- For or, ask whether the first part is True.
- Check the expression from left to right.
Practice answer
Analyze x >= 2 and (x/y) > 2 when x is less than 2 and y is zero.
Identify the guard: The first part, x >= 2, is the guard.
Evaluate the guard: Because x is less than 2, the guard is False.
Apply short-circuit evaluation: The and expression is already False, so Python skips the later division.
No division is attempted, so this expression does not raise ZeroDivisionError in this situation.
Key Takeaways
- Python evaluates logical expressions from left to right and stops when the result is already determined.
- An and expression short-circuits when its first part is False.
- An or expression short-circuits when its first part is True.
- The guardian pattern places a safe condition before a risky operation.
- Correct guard order can prevent runtime errors such as ZeroDivisionError and IndexError.
Key Takeaways
- Short-circuit evaluation means Python may skip later parts of a logical expression.
- The and operator stops on a False first part; the or operator stops on a True first part.
- A guardian condition must appear before the operation it protects.
- The guardian pattern can prevent errors by ensuring that a risky expression is evaluated only when its required condition is met.