Iterators in Python
Iterators are objects that allow you to access elements one at a time, without needing to store everything in memory. They help Python loop through sequences efficiently, making iteration smoother and more memory-friendly.
Every time you use a for loop, you are secretly using an iterator. Understanding how iterators work internally helps you write cleaner loops and even build your own custom iterable objects.
What Is an Iterable?
An iterable is any object capable of returning its elements one at a time. Lists, tuples, strings, dictionaries, and sets are the most common examples.
You can think of an iterable as a “container” that can produce values when needed but doesn’t give everything at once unless asked.
Examples of Iterable Objects
my_list = [10, 20, 30]
my_string = "Python"
my_tuple = (1, 2, 3)
What Is an Iterator?
An iterator is an object that remembers its current position and returns the next value when requested.
It works using two main methods: __iter__() to become iterable and __next__() to fetch the next value.
Iterators don’t restart automatically; once all values are consumed, calling next() again raises a StopIteration error.
Turning an Iterable Into an Iterator
numbers = [1, 2, 3]
iterator = iter(numbers)
print(next(iterator))
print(next(iterator))
print(next(iterator))
This manually fetches one value at a time, exactly how Python loops internally.
Why Do We Need Iterators?
Iterators allow Python to handle large data efficiently by producing values only when needed. They also form the base mechanism behind loops, generators, file reading, and many high-performance tools in Python.
Example: Looping With an Iterator
colors = ["red", "blue", "green"]
it = iter(colors)
for color in it:
print(color)
This works the same as a normal for loop, but now you understand the internal process.
Creating Your Own Iterator (Custom Class)
You can create custom iterator objects by defining __iter__() and __next__() inside a class.
This is useful when building objects that return data step-by-step, such as ranges, sequences, or controlled loops.
Example: Custom Iterator Counting 1 to 5
class Counter:
def __init__(self):
self.num = 1
def __iter__(self):
return self
def __next__(self):
if self.num <= 5:
value = self.num
self.num += 1
return value
else:
raise StopIteration
counter = Counter()
for value in counter:
print(value)
This demonstrates exactly how Python’s built-in iterators manage iteration behind the scenes.
Iterators vs Iterables
An iterable is a container (list, tuple, string). An iterator is the helper object that actually retrieves items one by one.
| Iterable | Iterator |
|---|---|
Has __iter__() |
Has __next__() |
| Stores all elements | Gets one element at a time |
| Examples: list, tuple, dict | Created by iter() |
Where Are Iterators Used in Real Life?
Iterators help process large files line by line without loading everything at once. They are also used when streaming data, reading logs, and handling data pipelines.
Whenever Python processes something step-by-step instead of all at once, an iterator is working behind the scenes.
📝 Practice Exercises
Exercise 1
Create an iterator that returns the letters of the word "Python" one by one.
Exercise 2
Use iter() and next() to print the first three elements of the list [5, 10, 15, 20].
Exercise 3
Build a custom iterator that counts backwards from 5 to 1.
Exercise 4
Explain in one sentence why iterators do not reset automatically.
✅ Practice Answers
Answer 1
word = "Python"
it = iter(word)
for char in it:
print(char)
Answer 2
nums = [5, 10, 15, 20]
it = iter(nums)
print(next(it))
print(next(it))
print(next(it))
Answer 3
class ReverseCounter:
def __iter__(self):
self.num = 5
return self
def __next__(self):
if self.num >= 1:
value = self.num
self.num -= 1
return value
else:
raise StopIteration
for i in ReverseCounter():
print(i)
Answer 4
Iterators do not reset because they are designed to remember their current position until all items are consumed.