When an expression mixes multiple operators, Python follows a strict precedence and associativity hierarchy to decide which operations run first. Understanding these rules ensures your code computes the values you intend and helps avoid subtle bugs.
1. Why Operator Precedence Matters
Without clear precedence rules, expressions like
4 + 6 * 2
would be ambiguous. Python defines:
- Precedence: Which operators bind tighter and execute earlier
- Associativity: How to group operators of the same precedence
Knowing these rules lets you write concise code without excessive parentheses—yet still get the correct result.
2. Precedence Table (High → Low)
Here’s a simplified list of key operator levels (from highest to lowest):
- Parentheses
( … ) - Exponentiation
**(right-to-left) - Unary
+x,-x,~x(right-to-left) - Multiplicative
*,/,//,% - Additive
+,- - Shifts
<<,>> - Bitwise AND
& - Bitwise XOR
^ - Bitwise OR
| - Comparisons
<,<=,>,>=,==,!=,is,in - Logical NOT
not(right-to-left) - Logical AND
and - Logical OR
or - Conditional
x if cond else y(right-to-left) - Lambda
lambda(right-to-left)
3. Associativity: Tiebreakers at the Same Level
When two operators share the same precedence, associativity decides evaluation order:
- Left-to-right: Most operators
- Right-to-left:
**, unary, conditional (x if cond else y), andlambda
Example:
2 ** 3 ** 2 # equals 2 ** (3 ** 2) → 512
4. Forcing Your Intent with Parentheses
Even if you know the rules, parentheses can:
- Self-document your intentions
- Prevent errors as expressions evolve
- Improve readability for collaborators
# Without parentheses: multiplication before addition
result1 = 4 + 6 * 2 # 16
# Explicit grouping
result2 = (4 + 6) * 2 # 20
5. Common Pitfalls & Tips
- Mixing logical and comparison operators can yield unexpected results. Always group with
()if clarity is needed:# Might surprise you if name == "Alice" or name == "Bob" and age >= 18: … # Better if (name == "Alice" or name == "Bob") and age >= 18: … - Chained comparisons are concise and safe:
1 < x < 10 # True if x is between 1 and 10 - Augmented assignment (
+=,*=) does not chain:a = b = 1 # valid # a = b += 1 # SyntaxError
6. Mini Project: Safe Expression Evaluator
Build a tiny REPL that parses and evaluates arithmetic expressions according to Python’s rules, without using eval():
import ast, operator
OPS = {
ast.Add: operator.add, ast.Sub: operator.sub,
ast.Mult: operator.mul, ast.Div: operator.truediv,
ast.Pow: operator.pow, ast.FloorDiv: operator.floordiv,
ast.Mod: operator.mod
}
def eval_node(node):
if isinstance(node, ast.BinOp):
left = eval_node(node.left)
right = eval_node(node.right)
return OPS[type(node.op)](left, right)
if isinstance(node, ast.Num):
return node.n
raise ValueError("Unsupported node")
def repl():
while True:
expr = input("Expr (or 'quit'): ")
if expr.lower() == "quit":
break
try:
tree = ast.parse(expr, mode="eval").body
print("Result:", eval_node(tree))
except Exception as e:
print("Error:", e)
if __name__ == "__main__":
repl()
How It Works:
- Uses Python’s AST to parse expressions
- Applies operator precedence and associativity naturally by the structure of the parse tree
- Handles basic arithmetic safely without
eval()
7. Conclusion
Mastering operator precedence and associativity helps you write concise, correct Python code without unexpected surprises. Always:
- Refer to the precedence table when combining diverse operators
- Use parentheses for clarity or to override defaults
- Test edge-case expressions interactively
With these tools in hand, you’ll tackle complex expressions with confidence. Happy coding!
Discover more from Affordable Tutor
Subscribe to get the latest posts sent to your email.


