Precedence and Associativity of Operators in Python


In Python, operators are special symbols that perform operations on variables and values. Understanding the precedence and associativity of operators is crucial for writing clear and accurate expressions. These concepts dictate the order in which operations are performed in an expression.

Table of Contents

  1. Introduction to Precedence and Associativity
  2. Operator Precedence in Python
  3. Operator Associativity in Python
  4. Common Operator Precedence Examples
  5. How to Override Precedence
  6. Best Practices for Using Operators

Introduction to Precedence and Associativity

  • Operator Precedence determines the order in which operators are evaluated in an expression. Operators with higher precedence are evaluated before those with lower precedence.
  • Operator Associativity refers to the direction in which operators of the same precedence level are evaluated. Most operators in Python are evaluated from left to right, but there are some exceptions, such as the exponentiation operator (**), which is evaluated from right to left.

Understanding these concepts ensures that your expressions are evaluated the way you intend and avoids mistakes or unexpected behavior in your programs.


Operator Precedence in Python

Operator precedence in Python follows a specific hierarchy. When multiple operators are present in an expression, Python evaluates the operators based on their precedence level, from highest to lowest.

Python Operator Precedence (Highest to Lowest)

Here’s a list of Python operators ordered by precedence:

Precedence Level Operator(s) Example
1 () (parentheses) (a + b) * c
2 ** (exponentiation) 2 ** 3
3 +, -, ~ (unary plus, minus, bitwise NOT) -a, +b, ~x
4 *, /, //, % a * b, a // b
5 +, - (addition, subtraction) a + b, a - b
6 <<, >> (bitwise shifts) a << b
7 & (bitwise AND) a & b
8 ^ (bitwise XOR) a ^ b
9 ` ` (bitwise OR)
10 ==, !=, >, <, >=, <= (comparison operators) a == b, a > b
11 not (logical NOT) not a
12 and (logical AND) a and b
13 or (logical OR) a or b
14 = (assignment) a = 5

Notes:

  • Parentheses () have the highest precedence and are used to group expressions, ensuring that enclosed expressions are evaluated first.
  • Exponentiation ** has higher precedence than multiplication, division, addition, and subtraction.
  • Bitwise operators (AND &, OR |, XOR ^, shifts <<, >>) have lower precedence than arithmetic operators like addition and multiplication but higher precedence than logical operators.

Operator Associativity in Python

Operator associativity dictates how operators of the same precedence level are evaluated.

Left-to-Right Associativity (Most Operators)

Most operators in Python evaluate from left to right (also known as left-associative). For example:

a = 5 + 2 * 3
# Here, multiplication has higher precedence, so 2 * 3 is evaluated first
# Then, the addition is performed: 5 + 6 = 11
print(a)  # Output: 11

Right-to-Left Associativity (Exponentiation and Assignment)

Some operators, such as the exponentiation operator (**) and assignment operators (=, +=, -=, etc.), evaluate from right to left (right-associative). For example:

a = 2 ** 3 ** 2
# Here, exponentiation is right-associative, so 3 ** 2 is evaluated first
# Then, 2 ** 9 is evaluated
print(a)  # Output: 512
a = b = 5
# The assignment is right-associative, so `b = 5` is evaluated first, then `a = 5`
print(a, b)  # Output: 5 5

Common Operator Precedence Examples

Example 1: Combining Multiple Operators

a = 5 + 3 * 2 - 8 / 4
# Multiplication (*) and division (/) have higher precedence than addition (+) and subtraction (-)
# The expression evaluates as: 5 + (3 * 2) - (8 / 4)
# Which results in: 5 + 6 - 2 = 9
print(a)  # Output: 9

Example 2: Using Parentheses to Control Precedence

a = (5 + 3) * (2 - 8) / 4
# Parentheses are evaluated first, so we get (8) * (-6) / 4
# Which results in: -48 / 4 = -12
print(a)  # Output: -12

Example 3: Exponentiation with Left-to-Right Evaluation

a = 2 ** 3 ** 2
# Exponentiation is right-associative, so 3 ** 2 is evaluated first (3 ** 2 = 9)
# Then 2 ** 9 is evaluated (2 ** 9 = 512)
print(a)  # Output: 512

How to Override Precedence

To avoid confusion and ensure your expressions are evaluated as intended, use parentheses to explicitly control the order of operations. Parentheses always have the highest precedence and can override the default precedence of operators.

For example, consider the following complex expression:

a = 5 + 2 * 3 ** 2  # Without parentheses, the result is 5 + 18 = 23
print(a)  # Output: 23

b = (5 + 2) * 3 ** 2  # With parentheses, the result is 7 * 9 = 63
print(b)  # Output: 63

By using parentheses, you ensure the intended order of operations is followed.


Best Practices for Using Operators

  1. Use Parentheses Liberally: When dealing with complex expressions, use parentheses to clarify your intent. This makes the code more readable and prevents errors related to operator precedence.

  2. Avoid Overly Complex Expressions: While Python allows for expressions with many operators, overly complex expressions can make the code hard to read. Break down long expressions into smaller, simpler steps.

  3. Know the Precedence and Associativity of Operators: Familiarize yourself with the precedence and associativity of operators to avoid mistakes, especially in mathematical and logical expressions.

  4. Comment Complex Expressions: If you have an expression with a mix of high and low precedence operators, include comments to explain the order of operations. This improves readability and understanding.