Skip to main content
MahiDev — Learn. Build. Become AI-ready.

Lesson 08

range — Numeric Sequence Type

Learn lazy numeric sequences with start, stop, and step, loop with range(), index and slice range objects, and why range() is memory efficient.

Beginner12 min

Visual reference

Number line and counting — integers in orderNumber line and counting — integers in order
For-loop and iteration conceptFor-loop and iteration concept
Efficient algorithms — small state, big sequencesEfficient algorithms — small state, big sequences

What you will learn

  • Three range forms — one, two, or three arguments
  • Exclusive stop — values run up to stop − 1
  • Default step — +1 when omitted
  • Lazy & immutable — no giant list in memory; no item assignment

Chapter 1 — Why range exists

Most programs repeat work: print ten lines, process every row, count down a timer. You need a sequence of integers with a fixed step (equal interval between values).

range is a built-in sequence type that represents that progression without storing every number upfront. It is the usual partner for for loops in Python.

Property range behavior
Type Pre-defined class, sequence
Purpose Integer values with equal step
Order Insertion / logical order preserved
Index / slice Yes
Mutability Immutable — no r[i] = ...

Chapter 2 — What is range?

Definition (your notes): range stores a sequence of numerical integer values by maintaining an equal interval (step) between values.

Think of it as a number line segment you walk along: start, end (exclusive), and stride.

range(10, 16) — start 10, stop 16 exclusive, step +1

Stop is never included. range(10, 16) yields 10, 11, …, 15 — not 16.

Chapter 3 — Syntax 1: range(stop)

Form: varname = range(value)

Meaning: integers from 0 to value − 1, step +1.

python
r = range(6)
print(r, type(r))

for val in r:
    print(val)
text
range(0, 6) <class 'range'>
0
1
2
3
4
5

range(6) and range(0, 6) describe the same sequence.

Chapter 4 — Syntax 2: range(start, stop)

Form: varname = range(start, stop)

Meaning: from start to stop − 1, default step +1.

Your notes: syntax 1 and syntax 2 both use default step +1.

python
r = range(10, 16)
print(r, type(r))

for val in r:
    print(val)

print(r[0])
print(r[-1])
print(r[0:4])

for val in r[0:4]:
    print(val)
text
range(10, 16) <class 'range'>
10 … 15
10
15
range(10, 14)
10 11 12 13

Bounds can be variables:

python
stop = 16
start = 10
step = 1

for val in range(start, stop, step):
    print(val)

Chapter 5 — Syntax 3: range(start, stop, step)

Form: varname = range(start, stop, step)

Meaning: from start toward stop − 1 (or below stop when counting down), advancing by step each time. Step may be positive (forward) or negative (backward).

python
r = range(10, 21, 2)
print(r, type(r))

for val in r:
    print(val)
text
range(10, 21, 2) <class 'range'>
10 12 14 16 18 20
python
for val in range(10, 21, 3):
    print(val)
text
10 13 16 19

Counting down

python
for val in range(9, 0, -1):
    print(val)
text
9 8 7 6 5 4 3 2 1
Negative step — walk left on the number line

Chapter 6 — Example sheet (your notes)

These patterns are equivalent where noted — practice reading range from the output:

Target sequence range(...) call
0–9 range(10) or range(0, 10) or range(0, 10, 1)
10–15 range(10, 16) or range(10, 16, 1)
9 down to 1 range(9, 0, -1)
100 down to 95 range(100, 94, -1)
10, 12, …, 20 range(10, 21, 2)
100, 110, …, 150 range(100, 151, 10)
−10, −20, …, −50 range(-10, -51, -10)
−100, −90, …, −50 range(-100, -49, 10)
−5 … 5 range(-5, 6) or range(-5, 6, 1)
python
print(list(range(-5, 6)))
print(list(range(-10, -51, -10)))
text
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5]
[-10, -20, -30, -40, -50]

Run the playground starter to compare forward, backward, and variable bounds.

Chapter 7 — Indexing and slicing

range supports indexing and slicing like other sequences. A slice returns another range object (lazy), not a list:

python
r = range(10, 16)
print(r[0:4])   # range(10, 14)

for val in r[0:4]:
    print(val)

Use list(r) when you need all values in memory at once.

Chapter 8 — Immutability

You cannot assign into a range:

python
r = range(10, 16)
# r[2] = 122
# TypeError: 'range' object does not support item assignment

Same idea as bytes: the sequence is fixed once created.

Chapter 9 — Why range is memory efficient

range(1_000_000) does not build a list of one million integers. Python stores only start, stop, and step, then computes each value when you loop or index.

Lazy range — three numbers, huge sequence
Approach Memory for huge counts
list(range(n)) Stores all n integers
range(n) in a for loop Stores three numbers + current value

That is why for i in range(1_000_000): stays practical.

Practice exercise

Print even numbers from 0 through 20 using a single range call:

python
for n in range(0, 21, 2):
    print(n, end=" ")
text
0 2 4 6 8 10 12 14 16 18 20

Predict before running: what is list(range(0, 10)[::2])?

text
[0, 2, 4, 6, 8]

Quick knowledge check

  1. What values does range(3) produce?
    0, 1, 2.

  2. Is the stop value included?
    No — stop is exclusive.

  3. Default step when omitted?
    +1.

  4. Can you write r[2] = 99 on a range?
    No — TypeError (immutable).

Summary

  • range models integer progressions with a fixed step for loops and conversions (list(range(...))).
  • Three forms: range(stop), range(start, stop), range(start, stop, step).
  • Stop is exclusive; default step is +1 in the one- and two-argument forms.
  • Immutable and lazy — efficient for large spans.

Next lesson: list — mutable collections of mixed values.

Loading playground…