Understanding Operator Precedence and Associativity in Python

This article is a complementary resource to the Learn Python Basics course.

Understanding Operator Precedence and Associativity in Python

In Python, operator precedence and associativity determine the order in which operations are performed in an expression.

Consider the following expression:

result = 10 - 5 + 3 * 2
print(result) 

You might expect the result to be -6 (i.e., (10 - (5 + 3)) * 2), but Python evaluates it as:

10 - 5 + (3 * 2) = 10 - 5 + 6 = 11

This happens due to operator precedence and associativity. Now, let's dive deeper into each concept.


What is Operator Precedence?

Operator precedence determines which operator is evaluated first in an expression. Operators with higher precedence are executed before those with lower precedence.

result = 10 - 5 + 3 * 2
print(result)  # Output: 11

In this case, multiplication (*) has a higher precedence than addition (+) and subtraction (-), so it gets evaluated first.


Operator Precedence Table

Here's an overview of operator precedence in Python (from highest to lowest):

Operator Description Precedence
() Parentheses Highest
** Exponentiation High
*, /, //, % Multiplication, Division, Modulo Medium
+, - Addition, Subtraction Lower
<, >, <=, >= Comparisons Low
==, != Equality/Inequality Lowest

What is Operator Associativity?

Associativity determines how operators of the same precedence are evaluated. Python follows two types of associativity:

  1. Left-to-right associativity: Most operators, like +, -, *, and /, are evaluated from left to right.
  2. Right-to-left associativity: Operators like exponentiation (**) and assignment (=) evaluate from right to left.

Example: Left-to-Right Associativity

Consider the following expression:

result = 20 - 5 - 3
print(result)  # Output: 12

Here, subtraction is evaluated left to right: (20 - 5) - 3 = 12.

Now, let's look at another example:

.

result = 10 / 2 * 3
print(result)  # Output: 15.0

In this case, both multiplication (*) and division (/) share the same precedence and are evaluated from left to right. So, division is performed first:

(10 / 2) * 3 = 15.0

Example: Right-to-Left Associativity

Exponentiation is right-to-left associative. Lets see an example,

result = 2 ** 3 ** 2
print(result)  # Output: 512

This is evaluated as 2 ** (3 ** 2).


Ambiguity in Complex Expressions

Without understanding precedence, it's easy to make mistakes. For example:

result = 10 / 2 / 2
print(result)  # Output: 2.5

You might expect 10.0, but Python evaluates it as (10 / 2) / 2 = 5 / 2 = 2.5.

To avoid such errors, always use parentheses to clarify your intentions.

result = 10 / (2 / 2)
print(result)  # Output: 10.0

Takeaway

To avoid confusion and ensure clarity, always use parentheses to explicitly define the order of operations in complex expressions.For example:

result = 10 / (2 * 3)
print(result)  # Output: 1.6666...

Here, parentheses ensure that 2 * 3 is evaluated first, changing the result of the division. Without parentheses, the division would be performed first, leading to a different result.

Using parentheses makes your intentions clear, eliminates ambiguity, and helps prevent logic errors.