range#

range is a lazy integer sequence. Constant-size regardless of length; range(10_000_000_000) is cheap because the values are computed on demand.

range(5)                       # 0, 1, 2, 3, 4
range(2, 10)                   # 2, 3, 4, 5, 6, 7, 8, 9
range(0, 100, 10)              # 0, 10, 20, ..., 90
range(10, 0, -1)               # 10, 9, ..., 1

range supports in, len, indexing, and slicing, all in constant time without materialising the sequence.

r = range(0, 100, 5)
r[3]                           # 15
r[-1]                          # 95
len(r)                         # 20
42 in r                        # False (42 is not on the stride)

Prefer enumerate(xs) over range(len(xs)); reach for range when the iteration is over the integers themselves, not the indices into a sequence.

Method catalog#

range is immutable; its method surface is the two sequence-protocol queries.

Method

Effect

index(value)

First position of value in the sequence; raises if missing.

count(value)

1 if value is in the sequence, else 0.

Read-only attributes.

Attribute

Effect

start

Inclusive lower bound.

stop

Exclusive upper bound.

step

Stride between successive values.

index finds a value’s position; raises if not in the range.

range(0, 100, 5).index(25)
5

count is 1 for values that are on the stride, 0 otherwise.

r = range(0, 100, 5)
r.count(25), r.count(26)
(1, 0)

Attributes report the construction parameters.

r = range(10, 100, 5)
r.start, r.stop, r.step
(10, 100, 5)

Operator overloading#

range implements the immutable-sequence dunders.

Operator

Dunder

Returns

r[i] / r[i:j]

__getitem__

Index (O(1)) or sub-range (O(1)).

i in r

__contains__

O(1) membership using start / stop / step arithmetic.

len(r)

__len__

Count of values in the range.

iter(r)

__iter__

Forward iteration.

reversed(r)

__reversed__

Reverse iteration without materialising.

a == b

__eq__

Equality (same elements in same order).

hash(r)

__hash__

Hash; range is hashable.

bool(r)

__bool__

False only when the range is empty.

__contains__ on range is O(1); it checks start / stop / step arithmetically without walking the sequence.

r = range(0, 10_000_000, 7)
7_777_777 in r, 7_777_778 in r
(True, False)

A class that supports __getitem__ plus __len__ slots into the same iteration protocol the operator’s tools expect.

class EvenRange:
    def __init__(self, n): self.n = n
    def __getitem__(self, i):
        if i >= self.n: raise IndexError
        return i * 2
    def __len__(self): return self.n

list(EvenRange(5))
[0, 2, 4, 6, 8]

References#