6

I have Python code at the moment which does something like this:

if plug in range(1, 5):
    print "The number spider has disappeared down the plughole"

But I actually want to check if the number is not in range. I've googled and had a look at the Python documentation, but I can't find anything. How can I do it?

Additional data: When running this code:

if not plug in range(1, 5):
    print "The number spider has disappeared down the plughole"

I get the following error:

Traceback (most recent call last):
    File "python", line 33, in <module>
IndexError: list assignment index out of range

I also tried:

if plug not in range(1,5):
     print "The number spider has disappeared down the plughole"

Which returned the same error.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Peter David Carter
  • 2,548
  • 8
  • 25
  • 44
  • 8
    `not in range(1, 5)`? – vaultah Apr 08 '16 at 19:38
  • Also, make sure `plug` is of type integer or the check does not work – karthikr Apr 08 '16 at 19:39
  • in range(-1000,1,) or in range(5,10000) ? (jk) – en_Knight Apr 08 '16 at 19:39
  • 2
    [`not` is actually has lower precedence than `in`](https://docs.python.org/3.5/reference/expressions.html#operator-precedence), so `plug not in range(1,5)` will work just fine. – Wayne Werner Apr 08 '16 at 19:42
  • What is line 33? You give an IndexError but that does not help us at all. It seems to be of another part of your code. In your additional code there is no list assignment taking place. You should give code that we can run and reproduce your problem with, which is now not the case – jusx Apr 08 '16 at 20:39
  • Line 33 was originally: `if plug not in range(1, 5)`. It wasn't working at the time of posting... – Peter David Carter May 02 '16 at 17:40
  • Note: this question was referenced on the recent Stack Overflow blog post: https://stackoverflow.blog/2022/05/27/games-are-good-mods-are-immortal-ep-446 in case questions arise about its activity starting/centered on 2022-05-27. – TylerH May 27 '22 at 18:41

5 Answers5

35

If your range has a step of one, it's performance-wise much faster to use:

if not 1 <= plug < 5:

Than it would be to use the not method suggested by others:

if plug not in range(1, 5)

Proof:

>>> import timeit
>>> timeit.timeit('1 <= plug < 5', setup='plug=3')  # plug in range
0.053391717400628654
>>> timeit.timeit('1 <= plug < 5', setup='plug=12')  # plug not in range
0.05137874743129345
>>> timeit.timeit('plug not in r', setup='plug=3; r=range(1, 5)')  # plug in range
0.11037584743321105
>>> timeit.timeit('plug not in r', setup='plug=12; r=range(1, 5)')  # plug not in range
0.05579263413291358

And this is not even taking into account the time spent on creating the range.

Markus Meskanen
  • 19,939
  • 18
  • 80
  • 119
  • Is it always faster for performance, or are there other dependent factors which might plausibly affect things? – Peter David Carter Apr 25 '16 at 09:58
  • 1
    @PeterDavidCarter I can't promise anything, but as far as I can think of, it's always faster to do it this way. Maybe if you're playing with multiple variables to make sure they're all outside of the range... In general, `range()` should be used for times when you need to use all the numbers within a range. In this scenario, you only need the begin and end points. – Markus Meskanen Apr 25 '16 at 15:01
  • I'm sort of curious, but would it be possible to actually look at the compiler code for Javascript to see why it's faster for myself? I'm sure you're right, I'd just be interested to learn more is all. All the Javascript libraries I'd probably just find them on Github, but JS itself... I'd be interested to start seeing things at a lower level, I think... – Peter David Carter Apr 26 '16 at 08:33
  • @PeterDavidCarter Javascript? You mean Python? You can use [`dis.dis()`](https://docs.python.org/3/library/dis.html) to see the disassembly of a function. – Markus Meskanen Apr 26 '16 at 10:35
  • Don't you mean `if _not_ 1 <= plug < 5` in the sample above? – Ray Feb 01 '19 at 09:24
  • Why was range added if it has a different performance??? Is it actually more performant for decimal-point numbers? If not why just not use < and > always? IF that is true why isn't range just a shorthand for < and > ? I'm getting some JS PTSD flashbacks reading this. – Bojidar Stanchev May 28 '22 at 01:49
  • @Bojidar, as Markus wrote in a comment, "In general, range() should be used for times when you need to use all the numbers within a range." If you need to iterate over the numbers from 10 to 20, `range` is your friend. It's not meant for testing membership (but see [Why is "1000000000000000 in range(1000000000000001)" so fast in Python 3?](https://stackoverflow.com/questions/30081275/why-is-1000000000000000-in-range1000000000000001-so-fast-in-python-3)) – alexis May 30 '22 at 09:32
5

This seems work as well:

if not 2 < 3 < 4:
    print('3 is not between 2 and 4') # which it is, and you will not see this

if not 2 < 10 < 4:
    print('10 is not between 2 and 4')

An exact answer to the original question would be if not 1 <= plug < 5:, I guess.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ebrahim Byagowi
  • 10,338
  • 4
  • 70
  • 81
1

Use:

if plug not in range(1,5):
     print "The number spider has disappeared down the plughole"

It will print the given line whenever variable plug is out of the range 1 to 5.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
0
if (int(5.5) not in range(int(3.0), int(6.9))):
    print('False')
else:
    print('True')

The value should be typecast to integer, otherwise not in range gives a strange result.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
-1
if not plug in range(1,5):
     #bla
jusx
  • 1,099
  • 9
  • 14
  • I was doing 'plug not in range()'. But this way doesn't seem to work either. Hhhmmmm... – Peter David Carter Apr 08 '16 at 19:38
  • @PeterDavidCarter `is` is checking for identity. While Python *mostly* reads like English, it's not actually English ;) – Wayne Werner Apr 08 '16 at 19:40
  • Why does it not work? This is very basic, it should work. Are you sure that plug is an integer? – jusx Apr 08 '16 at 20:02
  • I don't know. I posted the error it gave. I down-voted the above answer because it was just code and it didn't work, but if the answer is edited I may take it back because it seems possibly a little unfair now...? – Peter David Carter Apr 08 '16 at 20:17