← Python lessons

Python range(): len(), Indexing, in and reversed()

Part of a free Python course — sign up to save your progress and get AI hints.Sign up free

A range object is what range() returns: a compact sequence of whole numbers you can measure, index and search without looping over it.

Goal: answer questions about a range, such as "how many?", "what is last?" and "is this number in it?", without a loop.

Read The range() Function first. This lesson also uses len(), indexing and in from Lists. Every block runs on its own with fixed numbers and needs no setup.

See what a range really is

range() does not build a list. It stores only its start, stop and step, and works out each number when asked.

numbers = range(1, 11)
print(numbers)
print(list(numbers))

The first line prints range(1, 11), not the numbers. list() asks for every value, so the second line prints [1, 2, ..., 10].

Measure and index a range

A range supports len(), indexing and slicing, just like a list.

evens = range(0, 20, 2)
print(len(evens))
print(evens[0], evens[-1])
print(evens[2:5])

This prints 10, then 0 18, then range(4, 10, 2). A slice of a range is another range. Python computes all of these from start, stop and step, so len(range(1_000_000_000)) is instant.

Check membership with in

in tells you whether a number is one of the range's values.

evens = range(0, 20, 2)
print(6 in evens)
print(7 in evens)
print(20 in evens)

This prints True, False, False. 7 is skipped by the step, and 20 is the excluded stop. For whole numbers this is a quick calculation, not a search through every value.

Choosing reversed() or a negative step

Both count down. reversed() keeps the range you already think in; a negative step makes you shift both ends by one.

print(list(reversed(range(1, 6))))
print(list(range(5, 0, -1)))
print(list(range(5, 1, -1)))

The first two both print [5, 4, 3, 2, 1]. The third shows the usual slip: with stop 1 the 1 is left out, so it prints [5, 4, 3, 2]. Prefer reversed() when you start from an upward range, such as reversed(range(len(word))).

Watch out: empty ranges and whole numbers only

A range whose step points away from its stop is empty, with no error. A range also needs whole numbers.

print(len(range(5, 1)))
print(list(range(1, 5, -1)))
print(range(0, 1, 0.5))  # this line raises TypeError

The first two print 0 and []: the loop body would simply never run. The last line raises TypeError because 0.5 is not an int. A step of 0 raises ValueError.

Note: these examples keep ranges small and fixed. A range of a billion numbers costs almost no memory, but list() of it would try to store them all.

See also: Lists, Indexing.

Your turn

Finish describe() so it prints how many values r holds, its last value and whether target is one of them. Use len(), an index and in — no loop.

def describe(r, target):
    # print len(r), the last value of r, and whether target is in r
    pass

describe(range(3, 30, 3), 12)
describe(range(10, 0, -2), 1)

Expected output

9 27 True
5 2 False