Python Iterators — Core Concepts
Iterators are a foundational Python concept that powers for loops, comprehensions, generators, and many standard-library tools.
If you understand the iterator protocol, many “Python magic” behaviors become straightforward.
Iterable vs Iterator
- Iterable: an object you can loop over (list, tuple, dict, set, string, file)
- Iterator: object that returns one item at a time and remembers state
Protocol methods:
- iterable provides
__iter__() - iterator provides
__iter__()and__next__()
__next__() returns next item or raises StopIteration when done.
Built-ins: iter() and next()
items = ["a", "b", "c"]
it = iter(items)
print(next(it)) # a
print(next(it)) # b
print(next(it)) # c
When exhausted, next(it) raises StopIteration.
What for Loop Does Internally
Roughly equivalent logic:
it = iter(items)
while True:
try:
item = next(it)
except StopIteration:
break
print(item)
So for is cleaner syntax around the iterator protocol.
One-Shot Nature
Many iterators are consumed once:
it = iter([1, 2, 3])
print(list(it)) # [1, 2, 3]
print(list(it)) # []
After exhaustion, you need a new iterator.
Custom Iterator Class
class CountDown:
def __init__(self, start):
self.current = start
def __iter__(self):
return self
def __next__(self):
if self.current <= 0:
raise StopIteration
value = self.current
self.current -= 1
return value
for n in CountDown(3):
print(n)
This pattern is useful when stateful stepping logic does not fit standard containers.
Files Are Iterators Too
with open("app.log", "r", encoding="utf-8") as f:
for line in f:
if "ERROR" in line:
print(line.strip())
Reading line-by-line via iteration is memory-friendly for large files.
Helpful Iterator Tools
itertools provides efficient building blocks:
islicefor slicing streamschainfor concatenating iterableszip_longestfor uneven zipscount,cycle,repeatfor infinite iterators
from itertools import islice, count
first_five = list(islice(count(10), 5))
print(first_five) # [10, 11, 12, 13, 14]
Common Misconception
Misconception: lists and iterators are the same.
Lists are concrete collections with random access (items[2]). Iterators are streams with position, often no indexing, often one-pass.
Choosing iterator-based design can cut memory use and enable streaming pipelines.
Designing Iterator-Friendly Functions
A practical habit is to accept Iterable[T] in function inputs when random access is not required. That allows callers to pass lists, generators, file streams, or custom iterables. APIs become more reusable and easier to compose in data pipelines.
One Thing to Remember
The iterator protocol (
iter+next+StopIteration) is the hidden mechanism behind Python loops and streaming data workflows.
See Also
- Python Async Await Async/await helps one Python program juggle many waiting jobs at once, like a chef who keeps multiple pots moving without standing still.
- Python Basics Python is the programming language that reads like plain English — here's why millions of beginners (and experts) choose it first.
- Python Booleans Make Booleans click with one clear analogy you can reuse whenever Python feels confusing.
- Python Break Continue Make Break Continue click with one clear analogy you can reuse whenever Python feels confusing.
- Python Closures See how Python functions can remember private information, even after the outer function has already finished.