Chained Comparisons in PythonJanne Kemppainen |
This post is part of the Python bites series.
Can you chain comparison operations in Python? Yes you can, each comparison is evaluated pairwise so you can chain together as many of them you want.
It can be easy to forget to use basic features like this if you come from a language that doesn't support chained comparisons or if you've never seen them used in the wild. I've been using Python professionally for years but I have to admit that I still didn't really know about this feature until recently.
The classic case is to say that a value needs to be within a certain range. This can be expressed intuitively in Python:
if 1 <= x < 10: ...
It is equivalent to:
if 1 <= x and x < 10: ...
Chained comparisons act as if single comparisons were joined together with AND.
This causes some interesting properties. Take a look at this example.
if a < b < c < d: ...
Only the items around the operators are compared against each other so in theory this statement doesn't say anything about the relationship between
c, for example. However, with numerical values
a < c also holds true if the whole comparison evaluates to true (although your custom class could have some strange rock-paper-scissors comparison).
Now let's consider another example.
if a < b > c < d: ...
Note how the comparison between
c was flipped. I don't think this would fly in your mathematical essay but it is completely valid Python. Remember that the comparisons happen pairwise.
In this example we check that
a < b but we can't tell if
a < d is also true. Let's list the pairwise comparisons to make this clearer:
ais smaller than
bis greater than
cis smaller than
b is greater than both
d is guaranteed to be greater than
c but it can still be smaller than both
If you didn't understand a thing of what I'm trying to say here then you'll probably agree with me that you shouldn't use something like this in real code.
Bonus tip: If you need to check that the value is an integer between, for example one and ten, you can use the
if x in range(1, 11): ...
range() you just have to remember that the first value is included but the last one is not so you need to increment that by one. And because the Python 3 range implementation is lazy and doesn't return a list you can safely use it with large numbers too:
>>> 1234112 in range(1234, 98809810234981324) True