Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →To check whether a number falls between two values in Python, use a chained comparison. low < number < high tests an exclusive interval, where neither endpoint counts. low <= number <= high tests an inclusive interval, where both endpoints count. You choose < or <= separately for each side, so the same pattern covers closed, open, and half-open ranges.
Choose the boundary rule first
The comparison operator at each side decides whether that endpoint is included. Before writing any code, decide what should happen when the number equals a boundary.
| Interval you want | Expression | Lower bound | Upper bound |
|---|---|---|---|
| Closed (both ends included) | low <= number <= high |
included | included |
| Open (both ends excluded) | low < number < high |
excluded | excluded |
| Half-open, lower included | low <= number < high |
included | excluded |
| Half-open, upper included | low < number <= high |
excluded | included |
The half-open form is common when ranges are meant to tile without overlap. For example, age bands such as 18 up to but not including 30 can be written as 18 <= age < 30, so a value of exactly 30 lands in exactly one band.
Why the chained form is preferred
Python allows comparisons to be chained. The Python language reference states that comparisons can be chained arbitrarily, so that x < y <= z is equivalent to x < y and y <= z, with one difference: y is evaluated only once. If x < y is false, z is not evaluated at all.
Free tools Windows power users keep installed
One-click scans. No signup required.
#1 Best Overall
The longer form low < number and number < high gives the same result for simple values. It is only worth using when the surrounding logic reads better with separate conditions. For a single interval test, the chained form states the intent directly.
A worked example
score = 72
if 0 <= score <= 100:
print("within the allowed range")
Both 0 and 100 are accepted here. To reject 100 while keeping 0, change the second operator to <: 0 <= score < 100.
Rank #2
Edge cases that change the result
Reversed bounds
The chained test assumes the lower bound is actually lower. If low is greater than high, an ordinary ordered number cannot satisfy both comparisons, so the expression returns False for every input. Python does not reorder the bounds for you. If the bounds may arrive in either order and you want the range between them, normalize first:
low, high = sorted((low, high))
Only do this when a reversed pair is a valid input. If a reversed pair signals a bug, let the false result surface or raise an error instead.
Floating-point values
Comparisons test the values that are actually stored, not the decimal numbers you typed. A value that prints as 0.3 may be stored as a slightly different binary fraction, so a boundary check at exactly that point can behave unexpectedly. If your application treats values within a small distance of a boundary as equal, define that tolerance explicitly and apply it to the bounds. Do not quietly widen the interval.
NaN
An ordered comparison involving float('nan') returns False. A chained interval check that includes NaN therefore returns False, which can be a surprise if missing values are represented as NaN. Check for NaN explicitly with math.isnan() when that case needs its own handling.
Mixed types
Ordering depends on the operand types and how they compare. Numbers of different numeric types, such as int and float, compare correctly. A number compared with an unrelated type, such as a string, raises a TypeError in Python 3 rather than producing a range result. Convert inputs to the intended numeric type before the check.
Checking a whole column with pandas
For a pandas Series, the scalar chained comparison is not the right tool because you usually want one Boolean per row. Use Series.between(left, right, inclusive=...), which returns a Boolean Series and lets you choose endpoint inclusion.
Best Value
import pandas as pd
ages = pd.Series([17, 18, 30, 45])
mask = ages.between(18, 30, inclusive="left")
The inclusive argument has changed across pandas releases. Check the version you have installed with pd.__version__ and confirm the accepted values in that version’s documentation before relying on them. Filtering then works as usual, for example ages[mask].
Why range() is not an interval test
It is tempting to write number in range(low, high). That expression models a sequence of integers, with the stop value excluded, so it does not express a general numeric interval. It cannot represent floats at all, and it always excludes the upper endpoint. Use comparisons for ordinary numeric intervals, especially when the value may be a float or when the upper endpoint should be included.
Quick decision guide
- One scalar value, any endpoint rule: use a chained comparison.
- Bounds that may arrive reversed and should still define a range: sort them first.
- Values that may be NaN: handle NaN before or alongside the interval check.
- A pandas column that needs a Boolean per row: use
betweenwith the matchinginclusivesetting. - Integer sequences with an excluded stop value:
range()is the right tool, but it is not a general interval test.
The boundary operators and the reversed-bounds rule are the two decisions that most often change results, so verify both against the requirement rather than copying a pattern.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
Recommended Free Tools




