How do I determine whether a given integer is between two other integers (e.g. greater than/equal to 10000 and less than/equal to 30000)?
- 62,466
 - 11
 - 102
 - 153
 
- 6,885
 - 6
 - 21
 - 17
 
- 
                    30Check your boolean operators, of course a number will be greater than 10000 if it's greater than 30000. Look at the little details and you will catch far more mistakes. – Kaili Sep 17 '13 at 14:41
 - 
                    2Comparisons can be chained https://docs.python.org/2/reference/expressions.html#comparisons – theBuzzyCoder Aug 18 '17 at 06:52
 - 
                    18Pls change >= 30000 to <= 30000 – Badiboy Sep 17 '18 at 21:07
 - 
                    2The last edit made on this question is just putting "the solution" into the problem code. (makes the question somewhat invalid, defeats the purpose of this post I think.) – Caleb Dec 09 '20 at 20:35
 - 
                    The question clearly refers to the syntax of such comparison and has nothing to do with the number >= 30000 blunder. The edit was fine. – drakorg Jul 24 '21 at 04:37
 - 
                    @drakorg originally OP seems to have been asking because the typo in the code was causing wrong results. That should ordinarily have gotten the question closed, but there was a valid how-to question behind the wrong code. I removed the code from the question because it does not help understand the requirement, and because debugging a typo does not add value to Stack Overflow answers. – Karl Knechtel Mar 08 '23 at 15:51
 
16 Answers
if 10000 <= number <= 30000:
    pass
For details, see the docs.
- 3,491
 - 2
 - 28
 - 35
 
- 54,162
 - 23
 - 101
 - 92
 
- 
                    262Python is so nice :). And to be redundant: this is called "interval comparison." – Matt Montag Feb 11 '14 at 07:12
 - 
                    What is the speed difference between this and `if number in range(10000, 30001)` as suggested by other solution? Additionally, is it faster or slower when using `set` instead of `range`? – mc9 Aug 12 '15 at 00:37
 - 
                    26@MikeC With the interval comparison `number` is first compared against `10000`. If it's less than `10000` the expression is immediately short-circuited and the second comparison is not checked. The complexity is `O(1)`. `in range(0, n)` instead generates the entire sequence of numbers and then iterates through it. The complexity is `O(n)`. The complexity of `in set(range(0, n))` is still `O(n)` because building a set has a time complexity of `O(n)` https://www.ics.uci.edu/~pattis/ICS-33/lectures/complexitypython.txt – Paolo Moretti Aug 12 '15 at 12:16
 - 
                    10@MikeC Try to run in your shell: `> python -m timeit '10000 <= 10 <= 30000'` `> python -m timeit '10 in range(10000, 30001)'` `> python -m timeit '10 in set(range(10000, 30001))'` – Paolo Moretti Aug 12 '15 at 12:20
 - 
                    @SungWonCho, make sure to use `xrange` instead of `range` if you are testing on Python2 – John La Rooy Mar 09 '16 at 00:12
 - 
                    7looks like in python3.5.2, range is ~10x slower than the if statement, with speed constant in regard to range check value...thus most likely difference due to function overhead. – amohr Nov 10 '16 at 00:21
 - 
                    @SungCho not only ```if number in range(10000, 30001)``` is slow, it'll eat up a lot of unnecessary memory. it'll create all those numbers in a list and make a linear search, range is meant for loops where the index is needed. – Ian Elvister Mar 03 '21 at 21:37
 - 
                    1@IanElvister That's incorrect. `range` no longer creates a list in Python 3. See [Why is `10**15 in range(10**15+1)` so fast in Python 3?](/q/30081275/4518341) – wjandrea Sep 17 '22 at 20:29
 - 
                    Is there a way to add numbers with leading 0 in range , For ex: if number in range(00001,02021). I am getting the following error: SyntaxError: leading zeros in decimal integer literals are not permitted; use an 0o prefix for octal integers – Revanth Nov 08 '22 at 11:47
 
>>> r = range(1, 4)
>>> 1 in r
True
>>> 2 in r
True
>>> 3 in r
True
>>> 4 in r
False
>>> 5 in r
False
>>> 0 in r
False
- 
                    4Wow I always thought `range` (or `xrange` in python2) returns a generator thus you cannot repeatedly test on it. – yegle Mar 03 '14 at 16:44
 - 
                    If the test range is huge (e.g. `range(1000000000)`), using `xrange` in python2 is pretty slow. But `range` in python3 doesn't suffer from this problem. – yegle Mar 03 '14 at 19:02
 - 
                    @yegle range (in python3) does not return an iterator, it returns a range object. range objects can be iterated more than once. – compie Jun 17 '14 at 11:55
 - 
                    37Its important to so keep in mind that `4 in range(1,4)` is False. So better use the `1 >= r <= 4` as it avoids possible errors by newcomers – tripplet Jun 26 '14 at 08:01
 - 
                    72`1.5 in r` gives `False`, even in 3.4. This answer is only good for integers. – jpmc26 Jan 05 '16 at 17:49
 - 
                    1@jpmc26, good point. On the other hand you can specify a step size, so `range(1, n, 2)` lets you test for odd numbers. – John La Rooy Mar 09 '16 at 00:15
 - 
                    13@tripplet, you made the same error as the OP!, It should be `1 <= r <= 4` – John La Rooy Mar 09 '16 at 00:16
 - 
                    `timeit i=100; i in xrange(1000) 1000000 loops, best of 3: 1.17 µs per loop In [16]: timeit i=100; 1 <=i<=1000 10000000 loops, best of 3: 39.2 ns per loop ` Plus the bigger i the longer it works . – Sergey Sep 28 '17 at 12:22
 - 
                    10(1.) bad performance (as others have pointed out this syntax **looks good** but can take a long time to execute because it is O(n) operations vs the `if a <= x <= b`...) (2.) doesn't work for `float` types (3.) the range test is not-inclusive... so many developers may introduce bugs because they expect inclusive range – Trevor Boyd Smith Nov 03 '17 at 16:05
 - 
                    `x = 12000 RANGE_MIN = 10000 RANGE_MAX = 30000 if x == np.clip(x, RANGE_MIN, RANGE_MAX): print("x is OK")` – Enrique Pérez Herrero Dec 07 '20 at 08:56
 - 
                    @TrevorBoydSmith, I would say `x in range(...)` is not actually exhausting the range iterator according to this CPython implementation (https://github.com/python/cpython/blob/dc31334ab1b43225b65358fa361b46c22918b400/Objects/rangeobject.c#L383) – zhouhy Apr 25 '22 at 09:12
 
Use if number >= 10000 and number <= 30000:.  Alternately, Python has a shorthand for this sort of thing, if 10000 <= number <= 30000:.
- 62,466
 - 11
 - 102
 - 153
 
- 25,682
 - 5
 - 48
 - 63
 
- 
                    13... *this sort of thing* is typically called [*chained comparison*](https://docs.python.org/3/reference/expressions.html#comparisons). – Wolf Oct 30 '19 at 14:57
 
To check that the number is in the range 10000 - 30000, use the Python interval comparison:
if 10000 <= number <= 30000:
    print ("you have to pay 5% taxes")
This Python feature is further described in the Python documentation.
- 62,466
 - 11
 - 102
 - 153
 
- 2,078
 - 1
 - 16
 - 10
 
- 
                    You can also use it for the initial comparison, although it's as useless: if 10000 <= 30000 <= number: – Colin Pitrat Feb 01 '21 at 16:58
 
There are two ways to compare three integers and check whether b is between a and c:
if a < b < c:
    pass
and
if a < b and b < c:
    pass
The first one looks like more readable, but the second one runs faster.
Let's compare using dis.dis:
>>> dis.dis('a < b and b < c')
  1           0 LOAD_NAME                0 (a)
              2 LOAD_NAME                1 (b)
              4 COMPARE_OP               0 (<)
              6 JUMP_IF_FALSE_OR_POP    14
              8 LOAD_NAME                1 (b)
             10 LOAD_NAME                2 (c)
             12 COMPARE_OP               0 (<)
        >>   14 RETURN_VALUE
>>> dis.dis('a < b < c')
  1           0 LOAD_NAME                0 (a)
              2 LOAD_NAME                1 (b)
              4 DUP_TOP
              6 ROT_THREE
              8 COMPARE_OP               0 (<)
             10 JUMP_IF_FALSE_OR_POP    18
             12 LOAD_NAME                2 (c)
             14 COMPARE_OP               0 (<)
             16 RETURN_VALUE
        >>   18 ROT_TWO
             20 POP_TOP
             22 RETURN_VALUE
>>>
and using timeit:
~$ python3 -m timeit "1 < 2 and 2 < 3"
10000000 loops, best of 3: 0.0366 usec per loop
~$ python3 -m timeit "1 < 2 < 3"
10000000 loops, best of 3: 0.0396 usec per loop
also, you may use range, as suggested before, however it is much more slower.
- 14,289
 - 18
 - 86
 - 145
 
- 386
 - 4
 - 11
 
if number >= 10000 and number <= 30000:
    print ("you have to pay 5% taxes")
- 39,921
 - 24
 - 98
 - 123
 
Define the range between the numbers:
r = range(1,10)
Then use it:
if num in r:
    print("All right!")
- 149
 - 1
 - 3
 
- 
                    4`range` doesn't count the last value **10** in your case . `range(1,11)` is correct, if you need to compare between 1 and 10 – Ikbel Apr 18 '19 at 09:07
 
Python lets you just write what you mean in words:
if number in xrange(10000, 30001): # ok you have to remember 30000 + 1 here :)
In Python3, use range instead of xrange.
edit: People seem to be more concerned with microbench marks and how cool chaining operations. My answer is about defensive (less attack surface for bugs) programming.
As a result of a claim in the comments, I've added the micro benchmark here for Python3.5.2
$ python3.5 -m timeit "5 in range(10000, 30000)"
1000000 loops, best of 3: 0.266 usec per loop
$ python3.5 -m timeit "10000 <= 5 < 30000"
10000000 loops, best of 3: 0.0327 usec per loop
If you are worried about performance, you could compute the range once
$ python3.5 -m timeit -s "R=range(10000, 30000)" "5 in R"
10000000 loops, best of 3: 0.0551 usec per loop
- 62,466
 - 11
 - 102
 - 153
 
- 295,403
 - 53
 - 369
 - 502
 
- 
                    2
 - 
                    1@apraetor, yes use `range(10000, 30001)` in Python3. It doesn't create a list – John La Rooy Mar 02 '16 at 19:38
 - 
                    1your solution will iterate over 20 thousand integers. using <= and <= is much more efficient. – JBGreen Mar 08 '16 at 15:53
 - 
                    4@JBChouinard, you are absolutely incorrect. `xrange` in Python2, or `range` in Python3 have membership tests. Try it yourself if you don't believe. `<=` is only more efficient because it doesn't create a range object. Both ways as O(1). The point is the OP _was_ **trying to do it your way and ended up with a bug**. Fast code that is wrong is worse. – John La Rooy Mar 08 '16 at 18:05
 - 
                    2on an i5, (i)python 3.5: %timeit 5 in range(10000, 30000) 1000 loops, best of 3: 451 µs per loop. %timeit 10000 <= 5 <= 30000 10000000 loops, best of 3: 59.4 ns per loop. that's a factor of over 7000 – tback Nov 10 '16 at 10:03
 - 
                    1@tback, If there were a chance it was 7000 times slower, I would not have suggested it. Perhaps you could try running the test again. – John La Rooy Nov 11 '16 at 02:36
 - 
                    @tback I reran your tests and got ```timeit 5 in range(10000, 30000)``` ```428 ns ± 19.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)``` and ```%timeit 10000 <= 5 <= 30000``` ```71.6 ns ± 4.88 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)``` on an i7 python 3.6.3 so only 6x slower. – Techniquab Oct 12 '20 at 21:03
 
Below are few possible ways, ordered from best to worse performance (i.e first one will perform best)
     # Old school check
     if 10000 <= b and b <=30000:
        print ("you have to pay 5% taxes")
     # Python range check
     if 10000 <= number <= 30000:
        print ("you have to pay 5% taxes")
     # As suggested by others but only works for integers and is slow
     if number in range(10000,30001):
        print ("you have to pay 5% taxes")
- 92,761
 - 29
 - 141
 - 204
 
- 217
 - 2
 - 7
 
- 
                    1
 - 
                    `in range(...)` is quite fast, see the answers [here](https://stackoverflow.com/q/30081275/5320906). – snakecharmerb Aug 27 '23 at 12:12
 
While 10 <= number <= 20 works in Python, I find this notation using range() more readable:
if number in range(10, 21):
    print("number is between 10 (inclusive) and 21 (exclusive)")
else:
    print("outside of range!")
Keep in mind that the 2nd, upper bound parameter is not included in the range set as can be verified with:
>>> list(range(10, 21))
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
However prefer the range() approach only if it's not running on some performance critical path. A single call is still fast enough for most requirements, but if run 10,000,000 times, we clearly notice nearly 3 times slower performance compared to a <= x < b:
> { time python3 -c "for i in range(10000000): x = 50 in range(1, 100)"; } 2>&1 | sed -n 's/^.*cpu \(.*\) total$/\1/p'
1.848
> { time python3 -c "for i in range(10000000): x = 1 <= 50 < 100"; } 2>&1 | sed -n 's/^.*cpu \(.*\) total$/\1/p'
0.630
- 19,326
 - 11
 - 90
 - 127
 
- 
                    3Note that `10 <= 10.5 <= 20` is True while `10.5 in range(10, 21)` is False; depending on the situation, that may or may not be what you intend – Jiří Baum Oct 27 '21 at 09:43
 - 
                    While this is true for floats, OP precisely asked about integer comparison. – Lars Blumberg Oct 27 '21 at 13:55
 - 
                    Ah, so they have; in that case, the two expressions are indeed equivalent – Jiří Baum Oct 27 '21 at 22:17
 - 
                    If the bounds are pre-defined, there is no need to construct a new `range` object each time. Still slower than the `<= <=` construct, but it takes only 1.5× the time on my machine, not 3×. – tzot May 04 '23 at 08:50
 
Suppose there are 3 non-negative integers: a, b, and c. Mathematically speaking, if we want to determine if c is between a and b, inclusively, one can use this formula:
(c - a) * (b - c) >= 0
or in Python:
> print((c - a) * (b - c) >= 0)
True
- 3,326
 - 28
 - 48
 
- 
                    1this is the most obtuse possible way to do this and is less performant at the same time – Mattwmaster58 Jan 08 '23 at 10:46
 - 
                    
 
I'm adding a solution that nobody mentioned yet, using Interval class from sympy library:
from sympy import Interval
lower_value, higher_value = 10000, 30000
number = 20000
 # to decide whether your interval shhould be open or closed use left_open and right_open 
interval = Interval(lower_value, higher_value, left_open=False, right_open=False)
if interval.contains(number):
    print("you have to pay 5% taxes")
- 496
 - 8
 - 16
 
You want the output to print the given statement if and only if the number falls between 10,000 and 30,000.
Code should be;
if number >= 10000 and number <= 30000:
    print("you have to pay 5% taxes")
- 808
 - 2
 - 7
 - 21
 
- 17
 - 2
 
- 
                    6This answer has already been suggested. What does your answer add to the question? – Jaideep Shekhar Jan 11 '20 at 12:20
 
You used >=30000, so if number is 45000 it will go into the loop, but we need it to be more than 10000 but less than 30000. Changing it to <=30000 will do it!
- 9
 - 1
 
The condition should be,
if number == 10000 and number <= 30000:
     print("5% tax payable")
reason for using number == 10000 is that if number's value is 50000 and if we use number >= 10000 the condition will pass, which is not what you want. 
- 2,183
 - 2
 - 16
 - 20
 
- 9
 - 3
 
- 
                    This will fail for 10001, for example, though. He wants numbers between 10000 and 30000. Your condition will only work for number == 10000. – guerreiro May 01 '20 at 20:45
 - 
                    This will fail for the user's requirement. This is not an appropriate solution. – anjandash Aug 10 '20 at 15:42