Python Reference
range()
Generate a sequence of integers. Lazy — produces values on demand.
Last updated: October 2026
Definition: range(start, stop, step) generates a sequence of integers. The stop value is exclusive. In Python 3, range returns a lazy range object — it doesn't build the list in memory until you ask for it.
🎬 Live Example
Five common range patterns. Click any button to see the output.
💡 range is lazy in Python 3 — wrap in list() to see all values at once.
Basic Syntax
range(stop)
range(start, stop)
range(start, stop, step)
# stop is ALWAYS exclusive
# Returns a lazy range object in Python 3
🎯 Parameters
| Parameter | Default | Description |
|---|---|---|
start | 0 | First integer in the sequence (inclusive). |
stop | required | Boundary value (exclusive). |
step | 1 | Increment between numbers. Can be negative. |
The Stop-Exclusive Rule
list(range(5)) # [0, 1, 2, 3, 4]
list(range(1, 5)) # [1, 2, 3, 4]
list(range(1, 6)) # [1, 2, 3, 4, 5]
# If you want 1 through 5, use range(1, 6)
Most common bug: Forgetting stop is exclusive. range(5) gives 0-4, not 1-5.
Using the Step Parameter
list(range(0, 10, 2)) # [0, 2, 4, 6, 8]
list(range(0, 10, 3)) # [0, 3, 6, 9]
list(range(1, 10, 2)) # [1, 3, 5, 7, 9] — odd numbers
# Countdown
list(range(5, 0, -1)) # [5, 4, 3, 2, 1]
range Returns a Lazy Object
r = range(5)
print(r)
# range(0, 5) ← not [0, 1, 2, 3, 4]
# It's iterable
for n in r:
print(n)
# Convert to list when you need indexing
list(r) # [0, 1, 2, 3, 4]
Why lazy? Memory efficiency. range(1_000_000_000) creates almost no memory — values are generated on demand.
Iterating in Reverse
# Countdown
for i in range(10, 0, -1):
print(i)
# 10 9 8 7 6 5 4 3 2 1
# Iterate backwards through a list
items = ['a', 'b', 'c']
for i in range(len(items) - 1, -1, -1):
print(items[i])
# c b a
Real-World: Batch Processing
items = list(range(100))
batch_size = 10
for i in range(0, len(items), batch_size):
batch = items[i:i + batch_size]
process(batch)
# Processes in chunks of 10
🎯 range vs list vs enumerate vs zip
| Function | Returns | Use when |
|---|---|---|
range | Lazy sequence of ints | You need a numeric loop |
list | Materialized list | You need indexing or mutability |
enumerate | (index, value) pairs | You need index and value together |
zip | Tuples from multiple iterables | Parallel iteration |
⚠️ Common Mistakes
- Forgetting stop is exclusive.
range(1, 5)gives 1-4, not 1-5. - Expecting range to return a list. Wrap in
list()if you need one. - Using floats.
range(0, 1, 0.1)raises TypeError. Use numpy or while loop. - Zero step.
range(0, 10, 0)raises ValueError. - Storing the range in a variable for reuse in Python 2. Python 3 ranges are reusable — Python 2 xrange was not.
❓ Frequently Asked Questions
What does range() do in Python?
range() generates a sequence of integers. It takes start, stop, and step arguments. The stop value is exclusive — range(5) generates 0, 1, 2, 3, 4.
Is range() inclusive or exclusive?
range() is exclusive on the stop value. range(1, 5) generates 1, 2, 3, 4 — not 5. This is the most common gotcha.
Does range() return a list?
No. In Python 3, range() returns a lazy range object that produces numbers on demand. Wrap it in list() to get an actual list: list(range(5)).
Can range() count backwards?
Yes. Use a negative step: range(10, 0, -1) generates 10, 9, 8, ..., 1. The stop value is still exclusive.
Can range() use float steps?
No. range() only works with integers. For float steps, use numpy.arange() or a while loop.