Chaining comparison operators in Python (original) (raw)

Last Updated : 27 Feb, 2025

Checking multiple conditions in a single expression is common in programming. In Python, **comparison operator chaining allows us to write cleaner, more readable code when evaluating multiple conditions. Instead of using multiple and conditions, Python enables chaining comparisons directly in a mathematical-style expression.

**Traditional comparison syntax:

if a < b and b < c:

# Code block

**Using chaining:

if a < b < c:

# Code block

This is equivalent to a < b and b < c, but more concise and readable.

**Example:

Python `

x, y, z = 5, 10, 20

if x < y <= z: print("y is greater than x and less than or equal to z")

`

Output

y is greater than x and less than or equal to z

This is same as:

Python `

x, y, z = 5, 10, 20

if x < y and y <= z: print("y is greater than x and less than or equal to z")

`

Output

y is greater than x and less than or equal to z

However, in the chained version, y is evaluated only once, making it more efficient.

Key Properties of chained comparisons

Short-Circuit Evaluation

Short-circuit evaluation means that expressions are evaluated from left to right and evaluation stops as soon as the result is determined.

Python `

a, b, c = 10, 5, 20 print(a < b < c)

`

**Explanation: Since a < b is False, Python does not evaluate b < c, saving unnecessary computation.

No implicit relationship Between Non adjacent elements

Python does not assume a direct relationship between non-adjacent elements in a chained comparison. The comparisons are evaluated independently.

Python `

a, b, c = 5, 10, 2 print(a < b > c)

`

Explanation: This means a < c is not checked directly, only the individual conditionsa < b** and b > c.

Supports different operators

Python allows mixing different types of comparison operators within a single chained expression.

Python `

a = 25

if 18 <= a <= 30: print("Eligible")

`

**Explanation: This checks if a is between 18 and 30 in a single step.

**Works with identity & membership operator

Python also supports chaining with is and in operators, allowing for more complex and readable conditions.

Python `

x = [1, 2, 3] y = x print(y is x in [[1, 2, 3], x])

`

**Explanation: Here, x in [[1, 2, 3], x]checks if x is one of the elements in the list andy is **x**confirms they reference the same object.

Best Practice & Common Mistakes

**Best Practices:

**Common mistakes:

**Example: Incorrect usage:

Python `

x, y, z = 5, 10, 20

if x < y or y < z and z < x: # Incorrect print("Condition met")

`

**Explanation: Since **and has higher precedence than **or, x < y or y < z and z < x is evaluated as x < y or (y < z and z < x). Here, **y < z is True, but **z < x is False, making the and condition False. However, **x < y is True, so the overall expression is True, printing “Condition met.”

**Example: correct version

Python `

x, y, z = 5, 10, 20

if (x < y or y < z) and z > x: print("Condition met")

`

**Explanation: parentheses group ****(x < y or y < z)** and z > x, ensuring **x < y or y < z** evaluates to True, followed by ****z > x, which is also True, making the condition work as expected.

Performance Benefits of chainings

Chaining comparisons reduces redundant evaluations, improving execution speed. Instead of checking each condition separately, Python processes chained comparisons in a single pass, reducing the number of evaluations.

**Example: Performance comparison

Python `

import time

def compute(): time.sleep(1) return 100

a, b, c = 10, 20, compute()

start = time.time() result = a < b < c # Chained comparison end = time.time() print(f"Chained Comparison Time: {end - start:.2f} seconds")

start = time.time() result = a < b and b < c # Separate comparison end = time.time() print(f"Separate Comparison Time: {end - start:.2f} seconds")

`

**Chained Comparison Time: 0.00 seconds **Separate Comparison Time: 0.00 seconds

**Explanation: This code compares chained ****(a < b < c)** and separate (a < b and b < c) comparisons. Both take nearly the same time since **compute() runs once during assignment. However, chained comparisons are more efficient as they avoid redundant checks and improve readability.