Placement Prep

Python Operator Precedence and Associativity Guide

Master Python operator precedence and associativity with a full table, five traced examples, and the right-to-left rule that makes 2 ** 3 ** 2 return 512.

By FACE Prep Team 5 min read
python operators operator-precedence associativity python-programming placement-prep

Python evaluates operators in a strict priority order, and that order explains why 2 ** 3 ** 2 returns 512, not 64.

This is operator precedence: the rule that determines which operator Python processes first when an expression contains more than one. Get it wrong and you get silent arithmetic errors that pass syntax checks and produce the wrong answer. No interpreter warning. Just a bad result.

What Operator Precedence Means in Python

Consider 5 + 3 * 2. The result is 11, not 16.

Python applies multiplication before addition because * sits higher in the precedence table than +. The multiplication 3 * 2 = 6 runs first, then 5 + 6 = 11. If you need the addition to run first, parentheses enforce that: (5 + 3) * 2 = 16. Parentheses win every time.

This is the core rule: operators with higher precedence run before operators with lower precedence. Parentheses override everything else. Every other relationship is determined by where the operator sits in Python’s precedence hierarchy.

The rule applies across all operator types together. A bitwise shift (<<) has higher precedence than a comparison (==), which has higher precedence than logical and. When an expression mixes types, precedence is the only thing that determines evaluation sequence.

Python Operator Precedence Table

The Python 3 reference documentation defines the complete precedence table. The table below runs from highest priority to lowest:

Operator(s)Description
(), [], {}Parentheses, list/dict/set literals (highest)
**Exponentiation
+x, -x, ~xUnary plus, unary minus, bitwise NOT
*, /, //, %, @Multiplication, division, floor division, modulo, matrix multiply
+, -Addition, subtraction
<<, >>Bitwise left shift, right shift
&Bitwise AND
^Bitwise XOR
|Bitwise OR
==, !=, <, <=, >, >=, in, not in, is, is notComparison operators
not xLogical NOT
andLogical AND
orLogical OR
x if c else yConditional (ternary) expression
lambdaLambda expression
:=Walrus operator (lowest)

Two things stand out. First, ** sits well above *, /, +, and -. Exponentiation is not a “stronger multiply”; it sits in its own tier. Second, all comparison operators (==, !=, <, <=, >, >=, in, not in, is, is not) share a single row. They do not have sub-hierarchy among themselves. They chain instead of nesting.

Associativity: Left-to-Right vs Right-to-Left

Precedence tells Python which operator evaluates first when two operators are different. Associativity tells Python which evaluates first when two operators are the same, appearing in sequence.

Left-to-Right: the Default

Almost every Python operator is left-to-right. 10 / 2 / 5 evaluates as (10 / 2) / 5 = 5.0 / 5 = 1.0, not 10 / (2 / 5) = 25.0. The two / operations run left-to-right. Same for +, -, *, //, %, and the bitwise operators.

Right-to-Left: the Exponentiation Exception

Exponentiation reverses the default. 2 ** 3 ** 2 evaluates right-to-left: Python processes 3 ** 2 first, then uses that result as the exponent for the 2.

  • Step 1: 3 ** 2 = 9
  • Step 2: 2 ** 9 = 512

If Python used left-to-right, the result would be (2 ** 3) ** 2 = 8 ** 2 = 64. It doesn’t.

Comparison Chaining: Neither Left nor Right

Comparison operators do not associate in the normal sense. They chain. According to the Python documentation on comparisons, a < b < c is equivalent to (a < b) and (b < c), with b evaluated only once.

1 < 2 < 3 is not (1 < 2) < 3. It is (1 < 2) and (2 < 3). Both comparisons are checked independently. This Python-specific feature does not exist in C, Java, or most other languages. In C, 1 < 2 < 3 would compute (1 < 2) < 3 = 1 < 3 = 1 (true by coincidence). Python’s version is semantically cleaner.

Five Worked Examples Traced Step by Step

Each example below traces evaluation from the first operator applied to the final result.

Example 1: Mixed Arithmetic

print(5 + 3 * 2)
  • * has higher precedence than +
  • Step 1: 3 * 2 = 6
  • Step 2: 5 + 6 = 11
  • Output: 11

Example 2: Exponentiation Chain (Right-to-Left)

print(2 ** 3 ** 2)
  • ** is right-associative; rightmost exponentiation runs first
  • Step 1: 3 ** 2 = 9
  • Step 2: 2 ** 9 = 512
  • Output: 512

Left-to-right would give (2 ** 3) ** 2 = 8 ** 2 = 64. The correct answer is 512.

Example 3: Division Chain (Left-to-Right)

print(10 / 2 / 5)
  • / is left-associative; leftmost division runs first
  • Step 1: 10 / 2 = 5.0
  • Step 2: 5.0 / 5 = 1.0
  • Output: 1.0

Example 4: Logical NOT and Comparison

print(not 5 > 3)
  • > (comparison) has higher precedence than not
  • Step 1: 5 > 3 = True
  • Step 2: not True = False
  • Output: False

A common misreading is (not 5) > 3. In Python, not 5 evaluates to False because 5 is truthy; False > 3 is technically valid Python but semantically wrong for what the expression means. The correct parse is not (5 > 3).

Example 5: Comparison Chaining

print(1 < 2 < 3)
  • Python expands chained comparisons into an and expression
  • Equivalent to: (1 < 2) and (2 < 3)
  • Step 1: 1 < 2 = True
  • Step 2: 2 < 3 = True
  • Step 3: True and True = True
  • Output: True

The shared middle value (2) is evaluated once. If you write 1 < x() < 3 where x() has a side effect, that side effect happens exactly once.

Two Mistakes That Cost Marks in Assessments

Assuming Exponentiation Is Left-to-Right

Most candidates assume all same-precedence operators run left-to-right. ** breaks that assumption. In a Python MCQ that asks for the output of 2 ** 3 ** 2, the answer choices typically include both 64 and 512. Candidates who apply left-to-right get 64. The correct answer is 512.

The fix: memorise that ** is the one common operator in Python that runs right-to-left. Everything else above not runs left-to-right.

Forgetting not’s Low Precedence

not sits below all comparison operators in the table. not x == y means not (x == y), not (not x) == y. These produce different results when x and y differ. not 5 > 3 means not (5 > 3) = False, as traced above. If you find yourself writing not before a comparison expression, read the table once to confirm which side the not binds to.

Both mistakes appear in Python MCQs in campus assessments. The precedence table is the answer key: when in doubt, look up where each operator sits and work from the highest-precedence one down.

Programs that put these operators to work include a simple calculator in Python, where arithmetic precedence determines the output for every expression the user types, and finding the greatest of three numbers in Python, which chains comparison operators directly. For broader practice across expression types, Python basic programs covers the full operator set. The Armstrong number program uses ** for digit-power calculations, making it a clean test case for the right-to-left rule.

Understanding why 2 ** 3 ** 2 returns 512 makes more sense when you run it yourself and tweak the exponents. TinkerLLM provides a Python sandbox where you can trace operator evaluation live, check your mental model against real output, and work through the full precedence table interactively. Full access is ₹299.

Primary sources

Frequently asked questions

What is the highest-precedence operator in Python?

Parentheses () sit at the top of the precedence table. Any expression inside parentheses evaluates before anything else in the surrounding expression.

Is ** left or right associative in Python?

Exponentiation (**) is right-to-left associative. So 2 ** 3 ** 2 evaluates as 2 ** (3 ** 2) = 512, not (2 ** 3) ** 2 = 64.

What does not 5 > 3 return in Python?

It returns False. Comparison operators have higher precedence than not, so Python evaluates (5 > 3) = True first, then not True = False.

How does Python handle chained comparisons like 1 < 2 < 3?

Python expands chained comparisons into an and expression: (1 < 2) and (2 < 3), which is True and True = True. Each middle value is evaluated only once.

When should I use parentheses in Python expressions?

Use parentheses whenever an expression mixes operator types and the evaluation order is not immediately obvious. They override all other precedence rules and make your intent clear to both Python and the next reader.

What is the walrus operator and where does it fit in precedence?

The walrus operator (:=) assigns a value as part of an expression. It has the lowest precedence in Python, sitting below lambda expressions in the table.

Build AI projects

A self-paced playground for building with LLMs.

TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.

Try TinkerLLM (₹299 launch)
Free AI Roadmap PDF