Python Tutorial · Object-Oriented Python · Lesson 30 of 42

Python Iterators and Generators

How for loops work, and generators that produce values lazily with yield.

Iterables and iterators

A for loop calls iter() on an iterable to get an iterator, then calls next() until StopIteration:

Example 1Try it yourself
nums = [10, 20, 30]
it = iter(nums)
print(next(it))
print(next(it))
print(next(it))
try:
    next(it)
except StopIteration:
    print("done")

Output

10
20
30
done

Generators

A function containing yield is a generator: it produces values one at a time and pauses between them. This uses almost no memory, even for huge or infinite sequences.

Example 2Try it yourself
def countdown(n):
    while n > 0:
        yield n
        n -= 1

for value in countdown(3):
    print(value)

def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

fib = fibonacci()
print([next(fib) for _ in range(10)])

Output

3
2
1
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

Generator expressions

Like list comprehensions but with parentheses — values are computed lazily:

Example 3Try it yourself
squares = (n * n for n in range(1_000_000))
print(next(squares), next(squares))
print(sum(n * n for n in range(10)))

Output

0 1
285

Test yourself

Which keyword turns a function into a generator?

  1. return
  2. yield
  3. generate
  4. async
Show answer

Answer: yield

Practice next