hayaliv

hayaliv / Hi! Python / Level 2

Generators and lazy iteration

A generator function uses yield to hand back one item at a time, so you can stream records without building a full list.

Hi! Python · Level 2: Level 2: Writing reliable code · Checked against the Python 3.12 documentation · Updated 2026-10-17

Think of it like this

A generator is like reading a book aloud with a bookmark. You read one page, then stop. Next time you pick up exactly where the bookmark is. When you reach the last page, the book is finished.

Where the analogy stops being true. You can reopen a real book at page one, but a used-up generator cannot be rewound. You call the generator function again to get a new one.

What to know

Example

import io

def stream(lines):
    for line in lines:
        text, label = line.rstrip("\n").split("|")
        yield {"input": text, "label": label}

data = io.StringIO("call me|meeting_request\nstop|not_interested\nhi|unknown\n")
g = stream(data)
print(next(g))
print(list(g))
print(list(g))

It prints:

{'input': 'call me', 'label': 'meeting_request'}
[{'input': 'stop', 'label': 'not_interested'}, {'input': 'hi', 'label': 'unknown'}]
[]

Predict, then check

1. What does this print?

def count():
    print("start")
    yield 1
    yield 2

g = count()
print("made")
print(next(g))
Show the answer
made
start
1

Calling count() only builds the generator. The body starts at the first next(), so made prints before start.

2. What does this print?

def count():
    yield 1
    yield 2

g = count()
print(next(g), next(g))
try:
    next(g)
except StopIteration:
    print("done")
Show the answer
1 2
done

The two next() calls give 1 and 2. A third call finds the generator finished and raises StopIteration.

3. What does this print?

def evens(nums):
    for n in nums:
        if n % 2 == 0:
            yield n

g = evens([1, 2, 3, 4])
print(list(g))
print(list(g))
Show the answer
[2, 4]
[]

The first list(g) uses the generator up. The second one finds nothing left, so it gives an empty list.

Try it

Write a generator function long_replies(texts, min_words) that yields each text with at least min_words words (use len(text.split())), one at a time.

def long_replies(texts, min_words):
    return []
Show a solution
def long_replies(texts, min_words):
    for text in texts:
        if len(text.split()) >= min_words:
            yield text

Common mistake

A generator can be used only once. If you loop over it twice, the second loop gets nothing (the example's second list(g) prints []). Call the generator function again, or build a list, when you need a second pass.

In a small-language-model project

A training file can be too large to hold comfortably as one list. A good habit is to write a generator that reads and cleans one record at a time, then feed those records to your tokenizer or training loop.

Sources

Each quote below appears word for word on the cited page of the official Python documentation (version 3.12).

Step through this lesson in the Hi! Python desktop

← Exceptions