Python Boolean Operator Precedence

Mastering Logic Hierarchy & Short-Circuiting

Harold Nelson

2026-02-13

Introduction

In Python, complex expressions are evaluated based on a specific hierarchy. When multiple operators appear in a single line, precedence determines which part is evaluated first.

Why does this matter? * Prevents logic bugs. * Improves code readability. * Ensures efficient execution (Short-circuiting).

The “Big Three” Hierarchy

When dealing strictly with Boolean operators, Python follows this order of operations:

  1. not (Highest precedence)
  2. and
  3. or (Lowest precedence)

Mnemonic: Just remember NAO (like “Now”).

Comparison vs. Boolean Operators

Before Python even looks at and or or, it evaluates comparison operators. This allows expressions like x > 5 and y < 10 to work without extra parentheses.

Level Operators
1 Parentheses ()
2 Comparisons (<, >, ==, !=, is, in)
3 not
4 and
5 or

Level 1: not (Logical NOT)

The not operator is a unary operator, meaning it only takes one operand. It is evaluated before any other logical connectors.

# 'not' is evaluated before 'or'
result = not False or True 
# Becomes: (True) or True -> True

result_two = not (False or True)
# Parentheses force the 'or' first: not (True) -> False

Level 2: and (Logical AND)

The and operator has higher precedence than or. Think of and like multiplication and or like addition in standard math.

# This is NOT evaluated left-to-right
True or True and False

# Evaluation Process:
# 1. True and False -> False
# 2. True or False -> True

Level 3: or (Logical OR)

The or operator is the last to be evaluated. It acts as the “widest” net in your logic.

is_weekend = True
is_holiday = False
has_deadline = True

# evaluated as: is_weekend or (is_holiday and not has_deadline)
can_relax = is_weekend or is_holiday and not has_deadline

print(can_relax) # True

Short-Circuit Evaluation

Python is “lazy” (efficient). It stops evaluating as soon as the result is certain.

  • and: If the left side is False, the whole thing must be False. Python stops.
  • or: If the left side is True, the whole thing must be True. Python stops.
def check_server():
    print("Checking...")
    return True

# If the first part is True, 'check_server' never runs!
access_granted = True or check_server() 

Common Pitfall: Chained Comparisons

Python allows “chained” comparisons, which are often cleaner than explicit and statements.

age = 25

# Standard Logic:
if age > 18 and age < 30:
    pass

# Chained Logic (Pythonic):
if 18 < age < 30:
    print("In the range!")

Best Practice: Use Parentheses

Even if you know the precedence rules perfectly, readability is king.

  • Ambiguous: if a > b or c < d and e == f:
  • Explicit: if (a > b) or (c < d and e == f):

Parentheses remove ambiguity for other developers and ensure your logic remains robust during refactoring.

📝 Practice Exercise 1

What is the result of the following expression?

result = not True and False or True

Answer: True
Step-by-step: 1. not True \(\rightarrow\) False
2. False and False \(\rightarrow\) False
3. False or True \(\rightarrow\) True

📝 Practice Exercise 2

Will this code raise a ZeroDivisionError?

x = 10
y = 0

if x > 5 or (x / y) == 0:
    print("Success!")

Answer: No.
Reason: Short-circuiting. Because x > 5 is True, the or operator stops immediately and never evaluates the division by zero.

💡 Quick Reference Cheat Sheet

Task Operator / Rule
Strictness and requires both; or requires one.
Priority () > Comparisons > not > and > or.
Short-circuit False and ... stops; True or ... stops.
Grouping Always use () for mixed and/or for clarity.
Truthiness 0, "", [], None are False; almost everything else is True.

Summary

  • Comparisons happen before logical operators.
  • The order is not \(\rightarrow\) and \(\rightarrow\) or.
  • Short-circuiting can be used to prevent errors.
  • When in doubt, parenthesize.

Ternary Expressions

Python’s conditional expression (ternary operator) allows for a one-line if-else block.

Syntax: value_if_true if condition else value_if_false

age = 20
status = "Adult" if age >= 18 else "Minor"
print(status) # Output: Adult

Precedence in Ternary Expressions

The ternary operator has very low precedence. Almost every other operator (including or, and, and comparisons) is evaluated before the ternary choice is made.

# The 'or' and '==' are evaluated FIRST
x = 10
msg = "High" if x > 5 or x == 10 else "Low"

# This is effectively:
# "High" if (x > 5 or x == 10) else "Low"

Why Use Ternary Expressions?

  • Pros: Concise, great for simple assignments, and readable in moderation.
  • Cons: Hard to read if nested; can lead to “one-liner” obsession.

Avoid this “Nested” Mess:

# Technically valid, but practically a nightmare:
result = "A" if score > 90 else "B" if score > 80 else "C"

Tip: If it takes more than 2 seconds to read, use a standard if-else block.