Skip to main content

Operator Precedence and Associativity: Python Evaluation Order

Operator precedence determines the order in which Python evaluates operators in an expression—multiplication before addition, exponentiation before multiplication, and so on. Without understanding precedence rules, expressions like 2 + 3 * 4 will evaluate incorrectly in your mind (20 vs. the correct 14). Associativity defines the left-to-right (or right-to-left) order when operators have equal precedence. This guide explains both rules with a complete reference table and practical examples so you evaluate expressions confidently.


Key Takeaways

  • Operator Precedence: Determines evaluation order—parentheses highest, then exponentiation, then multiplication/division, then addition/subtraction, then comparisons, then logical operators.
  • Associativity: When operators have equal precedence, left-associative operators evaluate left-to-right (10 / 5 * 2 = 4); exponentiation is right-associative (2 ** 3 ** 2 = 512, not 64).
  • Parentheses Override: Always use parentheses () to clarify intent and avoid precedence bugs in complex expressions.
  • Complete Reference Table: Included below; bookmark it for quick lookup.

Why Operator Precedence Matters

Operator precedence determines the order in which Python evaluates operators in an expression. For example, in mathematics and Python, multiplication has higher precedence than addition, so:

result = 10 + 5 * 2  # 5 * 2 is evaluated first, then added to 10
print(result) # Output: 20

If Python evaluated left-to-right (ignoring precedence), 10 + 5 would be calculated first (15), then multiplied by 2 (30)—wrong. This rule is familiar from elementary math (PEMDAS: Parentheses, Exponents, Multiplication, Division, Addition, Subtraction), and Python follows the same conventions with additional operators.

Why This Matters in Practice: Precedence bugs are subtle and hard to debug. Consider:

# A common mistake in boolean logic
is_admin = False
is_owner = True
can_delete = is_admin or is_owner and False # What happens?

Without knowing precedence, this is ambiguous. Does and or or bind tighter? (Answer: and binds tighter, so this evaluates as is_admin or (is_owner and False) = False or False = False, not what the author intended.) Parentheses eliminate confusion.


Python Operator Precedence Reference Table

Here is the complete list of Python operators, ordered from highest to lowest precedence. Operators at the same level have the same precedence.

Precedence LevelOperatorsDescriptionAssociativity
1 (Highest)()Parentheses (function calls, grouping)N/A
2**Exponentiation (power)Right-to-left
3+x, -x, ~xUnary plus, unary minus, bitwise NOTRight-to-left
4*, /, //, %Multiplication, division, floor division, moduloLeft-to-right
5+, -Addition, subtractionLeft-to-right
6<<, >>Bitwise left shift, bitwise right shiftLeft-to-right
7&Bitwise ANDLeft-to-right
8^Bitwise XOR (exclusive OR)Left-to-right
9|Bitwise ORLeft-to-right
10==, !=, >, >=, <, <=, is, is not, in, not inComparisons and identity/membership operatorsLeft-to-right
11notLogical NOTRight-to-left
12andLogical ANDLeft-to-right
13 (Lowest)orLogical ORLeft-to-right

Operators are evaluated strictly in order from highest (1) to lowest (13). When multiple operators share the same precedence level, associativity determines the order.


Understanding Operator Associativity

When an expression contains multiple operators with the same precedence, associativity determines the order of evaluation.

Left-Associative Operators (Most Common)

Most operators are left-associative, meaning they are evaluated from left to right:

# Example 1: Subtraction (left-associative)
result = 100 - 50 - 10 # Evaluated as (100 - 50) - 10
print(result) # Output: 40

# NOT (100 - (50 - 10)) which would be 60
# Example 2: Division (left-associative)
result = 100 / 10 * 2 # Evaluated as (100 / 10) * 2
print(result) # Output: 20.0

# NOT 100 / (10 * 2) which would be 5.0

When operators have the same precedence and are left-associative, Python processes them left-to-right. This is intuitive for most operations.

Right-Associative Operators (Exception)

The exponentiation operator (**) is right-associative, meaning it is evaluated from right to left:

# Example 3: Exponentiation (right-associative)
result = 2 ** 3 ** 2 # Evaluated as 2 ** (3 ** 2), NOT (2 ** 3) ** 2
print(result) # Output: 512

# Step-by-step:
# 3 ** 2 = 9
# 2 ** 9 = 512

# If it were left-associative:
# 2 ** 3 = 8
# 8 ** 2 = 64 (incorrect)

This right-associativity makes mathematical sense: in algebra, 2^3^2 is universally understood as 2^(3^2) = 2^9 = 512.


Using Parentheses to Override Precedence

Parentheses () have the highest precedence and allow you to explicitly control the evaluation order. This is the clearest way to write complex expressions:

# Example 4: Clarifying intent with parentheses
result1 = 10 + 5 * 2
result2 = (10 + 5) * 2

print(f"Without parentheses: {result1}") # Output: 20
print(f"With parentheses: {result2}") # Output: 30

Best Practice: When an expression has more than 2–3 operators, use parentheses even if the precedence is "correct." Parentheses improve readability and prevent bugs:

# Without clarity, which is intended?
can_access = user.is_admin or user.is_owner and user.is_verified

# With parentheses, intent is explicit:
can_access = user.is_admin or (user.is_owner and user.is_verified)

Common Precedence Pitfalls

Pitfall 1: Logical Operators (and vs. or)

and has higher precedence than or:

# Common mistake
result = False or True and False
# Evaluated as: False or (True and False) = False or False = False
print(result) # Output: False

# Fix: Use parentheses for clarity
result = (False or True) and False
print(result) # Output: False

Pitfall 2: Comparison Chaining

Python allows comparison chaining, which can be deceptive:

# This looks like one expression but is actually two comparisons chained
result = 1 < 2 < 3
# Python evaluates this as: (1 < 2) and (2 < 3) = True and True = True
print(result) # Output: True

# Do NOT confuse with:
result = (1 < 2) < 3 # Evaluates to: True < 3 = 1 < 3 = True (unexpected!)
print(result) # Output: True (but semantically odd)

Pitfall 3: Modulo with Negative Numbers

Precedence can interact unexpectedly with negative numbers:

# Example: Unary minus (higher precedence than modulo)
result = -10 % 3
# Evaluated as: (-10) % 3, not -(10 % 3)
print(result) # Output: 2 (because Python's modulo returns positive for positive divisor)

# Compare:
result = -(10 % 3)
print(result) # Output: -1

Frequently Asked Questions

What happens if I mix operators of different precedence?

Python strictly follows its precedence table. Higher precedence operators are always evaluated first, regardless of position. Use the reference table above to determine order, and use parentheses if unsure.

Is there a difference between and/or in Python vs. other languages?

Yes. Python's and and or operators return the actual object (not a boolean), not just True/False. For example, 5 and 7 returns 7 (the second value), while 0 and 7 returns 0 (the first falsy value). This is called short-circuit evaluation and is intentional. Always use parentheses with these operators for clarity.

Should I always use parentheses?

Not always, but you should use them liberally. If an expression requires more than a second of mental parsing, add parentheses. Your future self will thank you, and code reviewers will appreciate the clarity.

How do I remember operator precedence?

Use the mnemonic PEMDAS from math class as a starting point (Parentheses, Exponents, Multiplication, Division, Addition, Subtraction), then refer to the table for Python-specific operators like bitwise and logical ops. Most Python developers keep a bookmark to the official precedence table.

Why is exponentiation right-associative?

In mathematics, exponentiation is universally right-associative. 2^3^2 means 2^(3^2), not (2^3)^2. Python mirrors this mathematical convention. It would be confusing if Python deviated from standard math notation.


Practice Challenge

Predict the output of the following expression, then verify in a Python interpreter:

result = 5 * 2 ** 3 + 4 / 2 - 1
print(result)

Step-by-step solution:

  1. 2 ** 3 = 8 (exponentiation first)
  2. 5 * 8 = 40 (multiplication, left to right)
  3. 4 / 2 = 2.0 (division, same level as multiplication, left to right)
  4. 40 + 2.0 = 42.0 (addition)
  5. 42.0 - 1 = 41.0 (subtraction)

Answer: 41.0


Conclusion

Operator precedence and associativity are fundamental rules that govern how Python evaluates expressions. By memorizing (or bookmarking) the precedence table, understanding left vs. right associativity, and using parentheses liberally, you will write expressions that are both correct and readable. Remember: parentheses are your friend and cost nothing—use them to clarify intent.


Further Reading