Python Comparisons in Depth
A chained comparison is a chain like 1 < x < 10. Python tests both ends against the middle.
The middle runs once
The function adds 1 to a counter each time it runs. The counter ends at 1, not 2.
calls = 0
def middle():
global calls
calls += 1
return 5
print(1 < middle() < 10)
print("Middle calls:", calls)Equal values across types
Numbers can match across int and float. Text never matches a number with ==.
print(1 == 1.0)
print("1" == 1)
print(0 == False)Same object or same value
The name b points at the same list as a. A fresh list with equal items is a new object.
a = [1, 2]
b = a
print(b is a)
print(b == [1, 2])
print([1, 2] is [1, 2])Sort with an old-style compare
The compare function returns a length gap. cmp_to_key turns it into a sort key.
from functools import cmp_to_key
def by_length(a, b):
return len(a) - len(b)
words = ["banana", "fig", "plum"]
print(sorted(words, key=cmp_to_key(by_length)))Example
nothing = None
flag = True
a = [1, 2]
b = a
print("1 == 1.0:", 1 == 1.0)
print('"1" == 1:', "1" == 1)
print("1 < 5 < 10:", 1 < 5 < 10)
print("nothing is None:", nothing is None)
print("flag is True:", flag is True)
print("b is a:", b is a)
print("b == [1, 2]:", b == [1, 2])Key points
- Chained comparison: a chain like 1 < x < 10.
- Python tests both ends against the middle.
- The middle of a chain is worked out only once.
- The sign == compares values.
- It can match across number types, like 1 and 1.0.
- The word is compares identity.
- It asks if two names point at the same object.
- Caching: Python may reuse some small ints and some strings.
- Never rely on that reuse with is.
- Use cmp_to_key to turn an old-style compare function into a sort key.
In this example, each line prints one tricky pair as a small truth table. The sign == matches 1 with 1.0, since both hold the same number value. It does not match the text "1" with the number 1. The chain 1 < 5 < 10 is true, since 5 sits between the ends. The word is is true for None, for True, and for b, which points at the same list as a. Every result here is guaranteed by the language, not by caching luck.
Note
Use is for the same object, None, and True or False checks.
Use == for plain values.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Python Playground
Exercise
A variable should be checked for no value at all. Which check is the right style?