Operator Precedence and Associativity
If you had an expression such as 2 + 3 * 4 , is the addition done first or the multiplication? Our high school maths tells us that the multiplication should be done first. This means that the multiplication operator has higher precedence than the addition operator.
Why Order Matters
Consider the expression 2 + 3 * 4. Does the addition happen first, or the multiplication? If you add first, you get (2 + 3) * 4 = 5 * 4 = 20. If you multiply first, you get 2 + (3 * 4) = 2 + 12 = 14. These are completely different results. Your high school mathematics taught you that multiplication should be done first, giving us 14. This is not arbitrary—it is a rule built into how programming languages evaluate expressions. Without such rules, the same expression could mean different things to different people, making programs unpredictable and unreliable.
Operator precedence is the set of rules that determines which operations are performed first when multiple operators appear in a single expression. Without these rules, expressions would be ambiguous.
Understanding Operator Precedence
Operator precedence is a hierarchy that ranks operators from highest to lowest binding strength. Operators with higher precedence are evaluated before operators with lower precedence, regardless of their position in the expression. In the expression 2 + 3 * 4, multiplication has higher precedence than addition, so Python evaluates 3 * 4 first to get 12, then adds 2 to get 14. This precedence rule applies consistently across all expressions, making the language predictable.
Python defines a complete precedence hierarchy for all its operators. The table of precedence runs from lowest precedence (least binding) at the top to highest precedence (most binding) at the bottom. This means that operators listed lower in the table are evaluated before operators listed higher in the table. For example, multiplication and division have higher precedence than addition and subtraction, which is why 2 + 3 * 4 evaluates to 14 and not 20.
Understanding Associativity
Associativity determines the order in which operators of equal precedence are evaluated. When two operators have the same precedence level, associativity tells us whether to evaluate from left to right or from right to left. Most operators in programming languages are left-associative, meaning they are evaluated from left to right. For example, subtraction is left-associative, so 10 - 5 - 2 is evaluated as (10 - 5) - 2 = 5 - 2 = 3, not as 10 - (5 - 2) = 10 - 3 = 7.
Associativity only matters when you have multiple operators of the same precedence level in a row. If operators have different precedence levels, precedence determines the order regardless of associativity. For instance, in 2 + 3 - 4 * 5, the multiplication happens first due to precedence, and then addition and subtraction are evaluated left to right due to their equal precedence and left-associativity.
Precedence Hierarchy
Python defines a complete precedence hierarchy for all operators. The following table lists operators from lowest precedence to highest precedence. Operators listed lower in the table bind more tightly and are evaluated before operators listed higher in the table.
| Precedence Level | Operators | Description |
|---|---|---|
| Lowest | or | Logical OR |
| and | Logical AND | |
| not | Logical NOT | |
| ==, !=, <, >, <=, >=, in, not in, is, is not | Comparisons and membership tests | |
| | | Bitwise OR | |
| ^ | Bitwise XOR | |
| & | Bitwise AND | |
| <<, >> | Bit shifts | |
| +, - | Addition and subtraction | |
| *, /, //, % | Multiplication, division, floor division, modulo | |
| +x, -x, ~x | Unary plus, unary minus, bitwise NOT | |
| Highest | ** | Exponentiation |
Python operator precedence from lowest to highest. Operators lower in the table are evaluated before operators higher in the table.
Overriding Precedence with Parentheses
Parentheses have the highest effective precedence in any expression. When you wrap part of an expression in parentheses, that part is evaluated first, regardless of the normal precedence rules. This allows you to override the default order of evaluation and make your intent explicit. For example, in the expression (2 + 3) * 4, the addition is forced to happen before the multiplication, giving us 5 * 4 = 20 instead of the default 2 + (3 * 4) = 14.
Using parentheses to explicitly group operators and operands is considered a best practice. It makes your code more readable and removes any ambiguity about your intentions, even if the parentheses are technically redundant according to precedence rules.
Evaluating Complex Expressions
When you encounter a complex expression with multiple operators at different precedence levels, evaluate it step by step by applying precedence and associativity rules. Start by identifying all the operators and their precedence levels. Then, repeatedly find the operator with the highest precedence and evaluate it, replacing that part of the expression with its result. Continue until only one value remains.
Evaluating a Complex Expression
Evaluate the expression: 2 + 3 * 4 - 5 / 2
Identify operators and precedence: The expression contains +, *, -, and / operators. Multiplication and division have higher precedence than addition and subtraction. Among operators of equal precedence, we apply left-to-right associativity.
Evaluate highest precedence operators first: Multiplication and division have equal precedence and are left-associative. We evaluate from left to right: 3 * 4 = 12, then 5 / 2 = 2.5. The expression becomes: 2 + 12 - 2.5
Evaluate remaining operators left to right: Addition and subtraction have equal precedence and are left-associative. We evaluate from left to right: 2 + 12 = 14, then 14 - 2.5 = 11.5
11.5
Common Mistakes
Assuming all operators are evaluated left to right
Operators have different precedence levels. Multiplication has higher precedence than addition, so it is evaluated first regardless of position.
Fix:
Remember that precedence determines order before associativity. Evaluate 3 * 4 first to get 12, then add 2 to get 14.Forgetting that subtraction is left-associative
Subtraction is left-associative, so operators of equal precedence are evaluated from left to right, not right to left.
Fix:
Evaluate (10 - 5) - 2 = 5 - 2 = 3 instead.Overestimating the precedence of addition
Multiplication has higher precedence than addition. Both multiplications are evaluated before the addition.
Fix:
Evaluate 2 * 3 = 6 and 4 * 5 = 20, then add them: 6 + 20 = 26.Not using parentheses for clarity, even when precedence is correct
While technically correct, it makes the code harder to read and more prone to misinterpretation by others.
Fix:
Use parentheses to make your intent explicit: a + (b * c) or (a + b) * c, depending on what you mean.
Practical Readability Advice
The Python documentation provides a complete precedence table for reference, but in practice, you should not memorize it. Instead, use parentheses to make your code self-documenting. This approach has three benefits: it makes your code immediately clear to anyone reading it, it reduces the likelihood of bugs caused by misunderstanding precedence, and it makes your code easier to modify later without introducing subtle errors.
Practice
Evaluate each of the following expressions step by step, showing which operations are performed first and why. Then, rewrite each expression using parentheses to make the order of operations explicit. 1. 5 + 2 * 3 2. 10 - 4 - 2 3. 2 * 3 + 4 * 5 4. 20 / 4 / 2 5. 2 + 3 * 4 - 5
Hints
- Remember that multiplication and division have higher precedence than addition and subtraction.
- For operators of equal precedence, evaluate from left to right unless parentheses override this.
- Check your work by adding parentheses to make the order explicit, then verify the result matches your step-by-step evaluation.
Key Takeaways
- Operator precedence is a hierarchy that determines which operations are evaluated first in an expression. Operators with higher precedence bind more tightly and are evaluated before operators with lower precedence.
- Associativity determines the order in which operators of equal precedence are evaluated. Most operators are left-associative, meaning they are evaluated from left to right.
- Parentheses override default precedence and force the enclosed expression to be evaluated first, regardless of normal precedence rules.
- To evaluate a complex expression, identify all operators, apply precedence rules first, then apply associativity rules to operators of equal precedence.
- Using parentheses to explicitly group operators and operands is a best practice that improves code readability and reduces the chance of errors, even when the parentheses are technically redundant.