Table of Contents
What does the Python range function do?
If you’re an experienced developer, or even a beginner, you’ve no doubt heard of the Python range()
function. But what does it do? In a nutshell, it generates a list of numbers, which is usually used to work with a for
loop. There are many uses for it. Often, it’s used when you need to perform an action X number of times, where you can use an index. In other cases, you may need to iterate over the list (or another iterated object) with access to the index. The range()
function has slight differences in how it works in Python 2.x and 3.x, but they still have the same concept. We will get to that a bit later.
Parameters range: star, stop, step
The range()
function takes three parameters, for example:
range(stop)
- stop: the number of integers to generate, starting from zero. For example,
range(3) == [0, 1, 2]
.
range([start], stop[, step])
- start: the number to start the sequence.
- stop: generates a number before the given number, but not including it.
- step: the difference between each number in the sequence.
Note:
- All parameters must be integers.
- Each of the parameters can be positive or negative.
range()
(and Python in general) is based on index 0, meaning that the list of indexes starts with 0, not 1, for example. The syntax that gives access to the first item in the list ismylist[0]
. Therefore, the last integer generated byrange()
depends onstop
, but will not include it. For example,range(0, 5)
generates integers 0, 1, 2, 3, 4, but does not include 5.
Examples of the range() function
Simple application with a for loop:
>>> # 5 numbers starting with 0
>>> for i in range(5):
print(i)
1
2
3
4
>>> # numbers from 3 to 6 (not including it)
>>> for i in range(3, 6):
print(i)
3
4
5
>>> # numbers from 4 to 10 (not including it) in steps of 2
>>> for i in range(4, 10, 2):
print(i)
4
6
8
>>> # numbers from 0 to -10 (not including it) in steps of -2
>>> for i in range(0, -10, -2):
print(i)
-2
-4
-6
-8
And this is an example of iteration over a list.
>>> my_list = ['one', 'two', 'three', 'four', 'five']
>>> my_list_len = len(my_list)
>>> for i in range(0, my_list_len):
print(my_list[i])
one
two
three
four
five
We passed the length of the list (5) as the stop
parameter. Range is useful in iterating with conditions. Consider the example of the song “99 Bottles of Beer on the Wall…” with the following code:
for i in range(99, 0, -1):
if i == 1:
print('1 bottle of beer on the wall, 1 bottle of beer!')
print('So take it down, pass it around, no more bottles of beer on the wall!')
elif i == 2:
print('2 more bottles of beer on the wall, 2 more bottles of beer!')
print('So take one down, pass it around, 1 more bottle of beer on the wall!')
else:
print('{0} bottles of beer on the wall, {0} bottles of beer!'.format(i))
print('So take it down, pass it around, {0} more bottles of beer on the wall!'.format(i - 1))
We get the following result:
99 bottles of beer on the wall, 99 bottles of beer!
So take one down, pass it around, 98 more bottles of beer on the wall!
98 bottles of beer on the wall, 98 bottles of beer!
So take one down, pass it around, 97 more bottles of beer on the wall!
97 bottles of beer on the wall, 97 bottles of beer!
So take one down, pass it around, 96 more bottles of beer on the wall!
...
3 bottles of beer on the wall, 3 bottles of beer!
So take one down, pass it around, 2 more bottles of beer on the wall!
2 more bottles of beer on the wall, 2 more bottles of beer!
So take one down, pass it around, 1 more bottle of beer on the wall!
1 bottle of beer on the wall, 1 bottle of beer!
So take it down, pass it around, no more bottles of beer on the wall!
Perfect! Finally you see the real power of Python. If you’re still a bit confused, I recommend reading the article 99 Bottles of Beer (Wikipedia).
range vs. xrange functions in python
You must have heard of the function known as xrange()
. This function was introduced in Python 2.x, and was renamed range()
in Python 3.x. So what’s the difference? In Python 2.x, range()
created a list, while xrange() returned an iterator, a sequence object. We can see this in the following example:
# Python 3.x
>>> range(1)
range(0, 1)
>>> type(range(1))
<class 'range'>
# Python 2.x
>>> range(1)
[0]
>>> type(range(1))
<class 'list'>
In Python 3.x. the range()
function has its own type. Simply put, if you want to use range()
in a for
loop, you can do so with ease. However, you can’t use it as a list object. For example, you can’t split a range
type into slices. When you use an iterator, each cycle of the for
statement outputs an instant subsequent number on the fly. Whereas the original range()
function produces all the numbers instantly before the for
loop starts executing. The problem with the original range()
function (in Python 2.x) was that it required a very large amount of memory to produce a large number. However, it can usually work faster with a small number of numbers. Note that in Python 3.x you can still create a list by passing the generator returned by list()
. In the following way:
>>> list_of_ints = list(range(3))
>>> list_of_ints
[0, 1, 2]
To see the difference in speed of action in range() and xrange(), see this article (english).
Using float with the range() function
Unfortunately, the range()
function does not support the float
type. Don’t let that upset you, though! We can easily use it with this function. There are several ways to do it, and here’s one of them.
>>> # all arguments are required
>>> def frange(start, stop, step):
i = start
while i >> for i in frange(0.5, 1.0, 0.1):
print(i)
0.5
0.6
0.7
0.8
0.9
1.0