0
0
Pythonprogramming~15 mins

Iteration using range() in Python - Deep Dive

Choose your learning style9 modes available
Overview - Iteration using range()
What is it?
Iteration using range() means repeating actions a certain number of times by counting numbers from start to stop. The range() function creates a sequence of numbers that you can loop over. This helps you run the same code multiple times without writing it again and again. It is a simple way to control how many times a loop runs.
Why it matters
Without range(), you would have to write repetitive code or manually count how many times to repeat actions, which is slow and error-prone. Range() makes loops easy, clear, and flexible, saving time and reducing mistakes. It helps programmers automate tasks, process lists, and build programs that do things repeatedly, like counting, processing data, or creating patterns.
Where it fits
Before learning iteration with range(), you should understand basic loops like for loops and simple counting. After mastering range(), you can learn more complex loops, list comprehensions, and how to iterate over different data types like strings or dictionaries.
Mental Model
Core Idea
Range() creates a list of numbers to count through, letting you repeat actions step-by-step in a loop.
Think of it like...
Using range() is like setting a timer to ring every minute for a set number of times, reminding you to do a task repeatedly until the timer stops.
range(start, stop, step)
  ↓     ↓     ↓
 [start, start+step, start+2*step, ..., stop-1]

Example:
range(0, 5, 1) → 0, 1, 2, 3, 4

Loop flow:
┌─────────────┐
│ Start loop  │
├─────────────┤
│ Get next n  │
├─────────────┤
│ Run code    │
├─────────────┤
│ Repeat until│
│ n reaches   │
│ stop value  │
└─────────────┘
Build-Up - 7 Steps
1
FoundationWhat is range() function
🤔
Concept: Introduces the range() function and its basic purpose.
The range() function creates a sequence of numbers. You can give it one, two, or three numbers: range(stop), range(start, stop), or range(start, stop, step). It always counts from start up to but not including stop, moving by step each time. If you only give one number, it counts from 0 to that number minus one.
Result
You get a sequence of numbers you can use to repeat actions in a loop.
Understanding that range() generates numbers lets you control how many times a loop runs without writing repetitive code.
2
FoundationUsing range() in a for loop
🤔
Concept: Shows how to use range() to repeat code multiple times with a for loop.
You can write: for i in range(5): print(i) This runs the print command 5 times, showing numbers 0 to 4. The variable i takes each number from the range sequence one by one.
Result
Output: 0 1 2 3 4
Knowing that the loop variable takes each number from range() helps you use it inside the loop for counting or indexing.
3
IntermediateCustom start and stop values
🤔Before reading on: do you think range(3, 8) includes the number 8? Commit to your answer.
Concept: Explains how to start counting from a number other than zero and where it stops.
range(3, 8) creates numbers starting at 3 up to but not including 8. So it gives 3, 4, 5, 6, 7. The stop number is always excluded. This helps when you want to count from a specific number.
Result
Output of for i in range(3, 8): print(i) is: 3 4 5 6 7
Knowing that the stop number is excluded prevents off-by-one errors, a common mistake in loops.
4
IntermediateUsing step to skip numbers
🤔Before reading on: does range(0, 10, 2) include the number 10? Commit to your answer.
Concept: Introduces the step parameter to control how much the count increases each time.
range(0, 10, 2) counts from 0 up to but not including 10, jumping by 2 each time. So it gives 0, 2, 4, 6, 8. Step can be any positive number to skip numbers or negative to count backwards.
Result
Output of for i in range(0, 10, 2): print(i) is: 0 2 4 6 8
Understanding step lets you create loops that count by twos, threes, or even backwards, making loops more flexible.
5
IntermediateCounting backwards with negative step
🤔
Concept: Shows how to use a negative step to count down instead of up.
You can write range(5, 0, -1) to count from 5 down to 1. The stop is still excluded, so it stops before 0. This creates 5, 4, 3, 2, 1.
Result
Output: 5 4 3 2 1
Knowing that negative steps count backwards helps you write loops that reverse through sequences or countdowns.
6
AdvancedRange object is lazy and memory efficient
🤔Before reading on: do you think range(1_000_000_000) creates a list of a billion numbers in memory? Commit to your answer.
Concept: Explains that range() does not create all numbers at once but generates them on demand.
Range returns a special object that produces numbers one by one when the loop asks for them. It does not store all numbers in memory, even if the range is huge. This makes it fast and memory-friendly.
Result
You can loop over very large ranges without slowing down or using lots of memory.
Understanding that range is lazy prevents confusion about performance and memory when working with big loops.
7
ExpertRange internals and slicing behavior
🤔Before reading on: does slicing a range object create a new list or another range? Commit to your answer.
Concept: Shows how range objects support slicing and indexing without creating lists.
Range objects support indexing and slicing like lists but return new range objects, not lists. For example, range(10)[2:7:2] returns a new range representing numbers 2, 4, 6. This keeps memory use low and allows chaining operations efficiently.
Result
Slicing a range gives another range object, not a list.
Knowing range slicing returns ranges helps write efficient code and avoid unexpected memory use.
Under the Hood
Range objects store only start, stop, and step values internally. When the loop requests the next number, the range calculates it on the fly using simple math: current = start + step * index. This avoids creating large lists in memory. The range object also supports indexing and slicing by adjusting these parameters to represent sub-sequences.
Why designed this way?
Range was designed to be memory efficient and fast, especially for large sequences. Creating full lists for big ranges would waste memory and slow programs. By calculating numbers as needed, Python keeps loops lightweight and scalable. Alternatives like lists were rejected because they don't scale well for large counts.
┌───────────────┐
│ Range Object  │
│  start       │
│  stop        │
│  step        │
└─────┬─────────┘
      │
      ▼
┌───────────────┐
│ On next() call│
│ calculate:    │
│ start + step* │
│ current index │
└─────┬─────────┘
      │
      ▼
┌───────────────┐
│ Return number │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does range(1, 5) include the number 5? Commit to yes or no.
Common Belief:Range includes the stop number in the sequence.
Tap to reveal reality
Reality:Range stops before the stop number; it never includes it.
Why it matters:Assuming the stop is included causes off-by-one errors, leading to loops running too many or too few times.
Quick: Does range(0, 10, 0) work without error? Commit to yes or no.
Common Belief:You can use zero as a step value in range().
Tap to reveal reality
Reality:Step cannot be zero; it raises a ValueError because counting by zero makes no sense.
Why it matters:Using zero step causes program crashes, confusing beginners who expect silent failure.
Quick: Does range(10) create a list of 10 numbers in memory? Commit to yes or no.
Common Belief:Range creates a full list of numbers in memory.
Tap to reveal reality
Reality:Range creates a lightweight object that generates numbers on demand, not a full list.
Why it matters:Misunderstanding this leads to inefficient code or fear of using large ranges unnecessarily.
Quick: Does slicing a range return a list? Commit to yes or no.
Common Belief:Slicing a range returns a list of numbers.
Tap to reveal reality
Reality:Slicing a range returns another range object, not a list.
Why it matters:Expecting a list can cause bugs when code tries to use list methods on the result.
Expert Zone
1
Range objects support membership tests efficiently by calculating if a number fits the sequence math instead of scanning all numbers.
2
Negative steps require careful start and stop values; if they don't align, the range can be empty, which is a subtle source of bugs.
3
Range objects are immutable and hashable, so they can be used as dictionary keys or set elements, which is uncommon for sequences.
When NOT to use
Range is not suitable when you need a mutable sequence or when the sequence is not numeric or evenly spaced. Use lists or other iterable types instead. For complex iteration patterns, generators or itertools provide more flexibility.
Production Patterns
In real-world code, range() is used for indexing lists, repeating tasks, and generating numeric sequences efficiently. It is common in data processing loops, pagination, and timed operations. Advanced uses include chaining ranges for complex slicing and using range objects as keys in caching.
Connections
List Comprehensions
Builds-on
Understanding range() helps grasp list comprehensions that often use range to generate lists concisely.
Arithmetic Sequences (Math)
Same pattern
Range() models arithmetic sequences, so knowing math sequences clarifies how start, stop, and step define the numbers generated.
Event Scheduling (Real-world Systems)
Analogous pattern
Range's step and counting resemble scheduling repeated events at fixed intervals, linking programming loops to real-world timing systems.
Common Pitfalls
#1Off-by-one error by including stop in range
Wrong approach:for i in range(1, 5): print(i) # expecting 1 to 5 inclusive
Correct approach:for i in range(1, 6): print(i) # stop is exclusive, so use 6 to include 5
Root cause:Misunderstanding that range excludes the stop number causes loops to miss the last intended value.
#2Using zero as step value
Wrong approach:for i in range(0, 10, 0): print(i)
Correct approach:for i in range(0, 10, 1): print(i) # step must not be zero
Root cause:Not knowing step cannot be zero leads to runtime errors.
#3Expecting range to create a list
Wrong approach:numbers = range(1000000) print(len(numbers)) # expecting list length
Correct approach:numbers = list(range(1000000)) print(len(numbers)) # convert to list if needed
Root cause:Confusing range object with list causes errors when list methods or properties are expected.
Key Takeaways
Range() creates a sequence of numbers from start up to but not including stop, stepping by a given amount.
Using range() in loops lets you repeat actions a set number of times without writing repetitive code.
Range objects are memory efficient because they generate numbers on demand, not storing all at once.
The stop value in range() is always excluded, which is a common source of off-by-one errors.
Range supports negative steps to count backwards and slicing to create sub-ranges without extra memory.