Chapter 10: Iterators, Generators & Comprehensions

Dive deep into Python’s iteration protocol, build generators for lazy evaluation, and use comprehensions for concise data transformations.

Download chapter10.py

Objectives

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

  1. Implement an iterator class Fibonacci that yields Fibonacci numbers up to n.
  2. Write a generator primes() that yields prime numbers indefinitely.
  3. Use a generator expression to compute the sum of squares of numbers 1–100 lazily.
  4. Flatten a nested list (e.g., [[1,2],[3,4]]) using a nested list comprehension.
  5. Given a dict mapping, write a dict comprehension to invert keys and values.