Chapter 10: Iterators, Generators & Comprehensions
Dive deep into Python’s iteration protocol, build generators for lazy evaluation, and use comprehensions for concise data transformations.
Downloadchapter10.py
Objectives
- Understand the iterator protocol:
__iter__()&__next__(). - Use built-in iterators with
iter()andnext(). - Create custom iterator classes.
- Write generator functions with
yield. - Use generator expressions.
- Build list, dict and set comprehensions.
1. Iterators & The Iteration Protocol
Any object implementing __iter__() and __next__() is an iterator:
# list is iterable, not iterator
lst = [1,2,3]
it = iter(lst) # get iterator
print(next(it)) # 1
print(next(it)) # 2
# StopIteration when exhausted
Custom iterator class:
class Counter:
def __init__(self, limit):
self.limit = limit
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current >= self.limit:
raise StopIteration
val = self.current
self.current += 1
return val
for i in Counter(3):
print(i) # 0,1,2
2. Generator Functions
Use yield to produce a sequence lazily:
def fib(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
for num in fib(5):
print(num) # 0,1,1,2,3
Generators maintain state automatically and raise StopIteration when done.
3. Generator Expressions
Compact syntax for generators:
# squares generator
squares = (x*x for x in range(10))
print(next(squares)) # 0
for sq in squares:
print(sq)
4. Comprehensions
a) List Comprehensions
# even squares 0–9
even_squares = [x*x for x in range(10) if x % 2 == 0]
b) Dict Comprehensions
# map to square
sq_map = {x: x*x for x in range(5)}
c) Set Comprehensions
# unique first letters
names = ["Alice","Bob","Anna"]
first_letters = {name[0] for name in names}
Exercises
- Implement an iterator class
Fibonaccithat yields Fibonacci numbers up ton. - Write a generator
primes()that yields prime numbers indefinitely. - Use a generator expression to compute the sum of squares of numbers 1–100 lazily.
- Flatten a nested list (e.g.,
[[1,2],[3,4]]) using a nested list comprehension. - Given a dict mapping, write a dict comprehension to invert keys and values.