What Is Operator Precedence and Associativity ?
When writing Python programs, you frequently combine different types of operators to solve complex problems. For example, a single line of code might mix addition, multiplication, comparisons, and logic like and or or.
Python does not simply read these long expressions from left to right. Instead, the Python interpreter relies on a strict mathematical framework consisting of two core layout rules: Operator Precedence and Associativity.
1. What is Operator Precedence ?
Operator Precedence acts like a built-in priority or "VIP ranking" system. It dictates which operator gets executed first when an expression contains multiple different operator symbols.
Think of it as Python’s version of the mathematical PEMDAS / BODMAS rule. An operator with a higher precedence rank will always bind more tightly to its surrounding values and execute before an operator with a lower precedence rank, regardless of its position in the line of code.
The Problem :
value = 5 + 3 * 2
If Python read strictly left-to-right, it would do 5
+ 3 = 8, and then 8 * 2 = 16.
The Reality: Python reads the line, recognizes that
Multiplication (*) has a higher priority ranking
than Addition (+), and evaluates the multiplication
first. Thus, it calculates 3 * 2 = 6, and then 5 + 6
= 11. The final answer is 11.
2. What is Operator Associativity ?
What happens when an expression contains two or more operators that have the exact same priority ranking? This is where Associativity comes into play as the ultimate tie-breaker.
Associativity determines the direction of execution—either Left-to-Right or Right-to-Left—when operators of equal rank appear side by side.
Left-to-Right Associativity (L-to-R)
The vast majority of operators in Python follow Left-to-Right associativity. This means that when a tie occurs, Python starts processing from the leftmost operator and works its way forward to the right. Example: Subtraction (-) and Addition (+) are perfectly tied in precedence.
result = 100 - 40 + 10
Because of L-to-R associativity, Python breaks the
tie by running the leftmost operator first:
1. Left operation: 100 - 40 = 60
2. Expression simplifies to: 60 + 10
3. Final operation: 60 + 10 = 70
Right-to-Left Associativity (R-to-L)
A few specific operators in Python reverse this rule, processing from the rightmost side backward to the left. The most prominent example is the Exponentiation (**) operator. Assignment operators (like =, +=) also evaluate right-to-left.
result = 2 ** 3 ** 2
Because exponentiation uses R-to-L associativity,
Python processes the rightmost tie first:
1. Right operation: 3 ** 2 (3 squared = 9)
2. Expression simplifies to: 2 ** 9
3. Final operation: 2 raised to the power of 9 = 512
The Master Python Precedence & Associativity Table
This master hierarchy table maps out all standard Python operators ordered from the absolute highest priority (executed first) to the absolute lowest priority (executed last).
| Priority Rank | Operator Symbols | Operator Group Name | Associativity Direction |
|---|---|---|---|
| 1 (Highest) | () | Parentheses (Brackets) | Left-to-Right |
| 2 | f(args...), x[index], x.attr | Function Calls, Indexing, Attributes | Left-to-Right |
| 3 | ** | Exponentiation (Power Math) | Right-to-Left |
| 4 | +x, -x, ~x | Unary Plus, Unary Minus, Bitwise NOT | Right-to-Left |
| 5 | *, /, //, % | Multiplication, Divisions, Modulus | Left-to-Right |
| 6 | +, - | Addition, Subtraction | Left-to-Right |
| 7 | <<,>> | Bitwise Shift Operators | Left-to-Right |
| 8 | & | Bitwise AND | Left-to-Right |
| 9 | ^ | Bitwise XOR | Left-to-Right |
| 10 | | | Bitwise OR | Left-to-Right |
| 11 | ==, !=, >, >=, <, <=, is, is not, in, not in | Relational Comparisons & Membership | Left-to-Right |
| 12 | not | Logical NOT | Right-to-Left |
| 13 | and | Logical AND | Left-to-Right |
| 14 | or | Logical OR | Left-to-Right |
| 15 (Lowest) | =, +=, -=, *=, /=, //=, %=, **= | All Assignment Operators | Right-to-Left |
Comprehensive Tracing: Step-by-Step Code Examples
Let’s dissect how Python processes multi-operator expressions behind the scenes by walking through execution traces.
Case 1: Overriding Priority using Parentheses ()
Parentheses sit at the absolute top of the priority ladder (Rank 1). You can wrap any expression in brackets to force Python to ignore standard ranking rules.
# Standard priority math vs Manual override math
normal_calculation = 20 + 4 * 5
bracket_calculation = (20 + 4) * 5
print("Normal calculation:", normal_calculation) # Output: 40
print("Bracket calculation:", bracket_calculation) # Output: 120
1. Scan Phase : Python looks at the
expression and hits the Parentheses (). It freezes
all other external logic.
2. Inner Bracket Phase : It steps
inside the brackets to compute 20 + 4. This resolves
perfectly to 24.
3. Simplification Phase : The
expression collapses down and transforms into 24 *
5.
4. Final Phase : Python executes
the multiplication operator, calculating 24 × 5 =
120.
Case 2: Mixing Relational Comparisons and Logical Operators
A highly common source of bugs for beginners is combining numerical checks with logical gateways like and or or. Let's analyze how they compete in ranking.
score = 85
is_eligible = score > 90 or score < 100 and score == 85
print("Eligibility status:", is_eligible) # Output: True
1. Scan Phase : Python maps the
entire expression: score > 90 or score < 100 and
score==85.
2. Step 1 (Relational Check First)
: Relational comparison operators
(>, <,==at Rank 11) have a much higher priority
than logical and / or. Python evaluates all
comparisons from Left-to-Right :
Comparison A: score > 90 → 85 > 90 evaluates
to False
Comparison B: score < 100 → 85 < 100
evaluates to True
Comparison C: score == 85 → 85 == 85
evaluates to True
3. Simplification Phase 1
: The long statement
reduces down to a clean Boolean string:
False or True and True.
4. Step 2 (The Logical Conflict)
: Python now processes the
remaining logical operators: or and and.
Looking at our master table, and (Rank
13) has a higher precedence than or
(Rank 14).
5. Step 3 (Executing and)
: Python isolates the and
evaluation first: True and True.
Following standard AND rules, this
resolves to True.
6. Simplification Phase 2
: The statement reduces to
its final combination: False or True.
7. Final Step : Python
evaluates the or condition. Since one
side is True, the entire structure
returns a final answer of True.
Case 3: The Traps of Mixed Assignment Chains
Because assignment operators follow Right-to-Left associativity, chaining multiple assignments together creates a cascading execution waterfall moving backward.
# Initializing three separate variables to a single target number simultaneously
x = y = z = 50
print(f"x: {x}, y: {y}, z: {z}") # Output: x: 50, y: 50, z: 50
1. Scan Phase : Python analyzes the
chained sequence: x = y = z = 50.
2. Step 1 : Assignment operators
apply Right-to-Left associativity. Python looks at
the extreme right of the equation first: z = 50. It
stores 50 inside variable z.
3. Step 2 : The operation returns
the value 50 backward to the next assignment link: y
= z. Since z is now holding 50, y receives 50.
4. Step 3 : The operation passes
the value backward to the final link: x = y.
Variable x receives 50.