What is the difference between random.randint and randrange?

Viewed 125603

The only differences between randrange and randint that I know of are that with randrange([start], stop[, step]) you can pass a step argument and random.randrange(0, 1) will not consider the last item, while randint(0, 1) returns a choice inclusive of the last item.

So, I don't understand why randrange(0, 1) doesn't return 0 or 1. Why would I use randrange(0, 2) instead of a randrange(0, 1) which does?

5 Answers

A range in python is something that includes the lower-bound but does not include the upper-bound. At first, this may seem confusing but it is intentional and it is used throughout python.

list(range(4, 10))
#     [4, 5, 6, 7, 8, 9]
#     does not include 10!

xs = ['a', 'b', 'c', 'd', 'e']  
xs[1:4]  
#     [xs[1], xs[2], xs[3]] 
#     does not include xs[4]!

bisect.bisect_left('jack', names, 2, 5)
#     perform a binary search on names[2], names[3], names[4]
#     does not include names[5]!

random.randrange(4, 8)
#     picks a random number from 4, 5, 6, 7
#     does not include 8!

In mathematics, this is called a half-open interval. Python chooses to use half-intervals because they avoid off-by-one errors:

[to avoid off-by-one errors] ... ranges in computing are often represented by half-open intervals; the range from m to n (inclusive) is represented by the range from m (inclusive) to n + 1 (exclusive)

And so as a result, most python library functions will use this idea of half-open ranges when possible.

However randint is one that does not use half-open intervals.

random.randint(4, 8)
#     picks a random number from 4, 5, 6, 7, 8
#     it does indeed include 8!

The reason is historical:

  • randint was added early in v1.5 circa 1998 and this function name was used for generating both random floating-point numbers randomly and integers randomly
  • randrange was added in python in v1.5.2. In v2.0, a notice was added saying that randint is deprecated.
  • the deprecation notice for randint has since been removed

randint started off as an earlier library function that didn't include half-open interval because this idea was less cemented in python at the time.

Actually... randint() uses randrange() to generate random integers.

>>> randint(1.0,2.1)
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    randint(1.0,2.1)
  File "C:\Users\Anonymous\AppData\Local\Programs\Python\Python37\lib\random.py", line 222, in randint
    return self.randrange(a, b+1) <----- LOOK HERE
  File "C:\Users\Anonymous\AppData\Local\Programs\Python\Python37\lib\random.py", line 195, in randrange
    raise ValueError("non-integer stop for randrange()")
ValueError: non-integer stop for randrange()
Related