Legends ofPythos
Claim your name
Pythonic Python

Generators and yield

Lesson 3 of 12

Watch the lesson1:24 · with Sigrid
A generator works like a ticket machine at a stadium: instead of printing all tickets for ten thousand fans at once, it prints one when you ask and waits until you request the next. In Python, this means using yield inside a function to pause execution and hand back values one at a time.

The Mental Model

def count_up(n):
    for i in range(1, n + 1):
        yield i

g = count_up(3)
print(next(g)) # Prints 1. Function pauses at 'yield'.
print(next(g)) # Prints 2. Resumes where it left off.
print(list(g)) # Prints [3]. Finishes the loop.
count_up hands over one value at a time, pausing at each yield.
Notice that count_up returns a generator object, not the numbers themselves. The code inside does not run until you ask for values by calling next() or looping over it. This is lazy evaluation: work happens only when needed.

Why Lazy Evaluation Matters

def temp_readings(n):
    # Imagine reading from a slow sensor
    for i in range(1, n + 1):
        yield 20.5 + (i * 0.1)

total = sum(temp_readings(5)) 
print(total)
A lazy sequence for temperature logs.
The example above calculated the sum without storing five temperatures simultaneously. This matters when processing large log files or streaming data, where holding everything in a list would crash your memory.

Generator Expressions

You can write a one-line generator using parentheses ( ) instead of square brackets [ ]. It looks like a list comprehension but produces values lazily. This is useful for chaining operations without creating intermediate lists.
# Eager: creates [1, 4, 9] in memory
squares_list = [x * x for x in range(1, 4)]
print(squares_list)

# Lazy: produces values one by one on demand
lazy_squares = (x * x for x in range(1, 4))
print(next(lazy_squares)) # Prints 1
print(list(lazy_squares)) # Prints [4, 9]
Lazy squares vs eager list.
def one_shot():
    yield "first"
    yield "second"

seq = one_shot()
print(list(seq)) # ['first', 'second']
print(list(seq)) # [] - Empty! It's exhausted.
Single-use nature of generators.

Your turn

0 of 3 solved

Exercise 1

+40 XP
Write a generator function called evens(n) that lazily yields every even number from 2 up to and including n (inclusive). It should yield nothing if n < 2.

Hint: loop with range(2, n + 1, 2) or check i % 2 == 0.
def evens(n):
    pass

Run your code to check it against the tests.

Exercise 2

+40 XP
Write a generator function called take(n, iterable) that lazily yields at most the first n items from any iterable (list, range, another generator). If n is 0 or negative it should yield nothing.

Hint: loop with for item in iterable and use a counter; break once you have yielded n values.
def take(n, iterable):
    pass

Run your code to check it against the tests.

Exercise 3

+40 XP
Create a generator expression (round brackets, not square) called lazy_squares that produces the squares of 1 to 50. Then add them up into total and print it.
Write your Python here.

Run your code to check it against the tests.