Exploring Generators in Python

O

Ohidur Rahman Bappy

MAR 22, 2025

Exploring Generators in Python

Introduction

Python offers a powerful tool called generators to create custom iterator functions. A generator is a special function that returns an iterator object, allowing you to iterate over a sequence of values. Unlike regular functions, generators use the yield statement instead of return.

Understanding Generators

Here is a simple generator function:


def myGenerator():
    print('First item')
    yield 10

    print('Second item')
    yield 20

    print('Last item')
    yield 30

In the above example, myGenerator() uses yield to return values one at a time. To utilize this generator, you need to create an iterator as shown below:

>>> gen = myGenerator()
>>> next(gen)
First item
10
>>> next(gen)
Second item
20
>>> next(gen)
Last item
30

Yield vs Return

Using return in a generator terminates the function, unlike yield, which pauses the execution while maintaining internal states. Consider the following example:


def myGenerator():
    print('First item')
    yield 10

    return 

    print('Second item')
    yield 20

    print('Last item')
    yield 30

Running the generator:

>>> gen = myGenerator()
>>> next(gen)
First item
10
>>> next(gen)
Traceback (most recent call last):
...
StopIteration

Generators with Loops

Generators can also leverage loops:


def getSequenceUpTo(x):
    for i in range(x):
        yield i

This allows the function to yield values within a loop:

>>> seq = getSequenceUpTo(5)
>>> for num in seq:
>>>     print(num)
0
1
2
3
4

Advanced Example: Squares Generator

Consider a generator that yields square numbers:


def squareOfSequence(x):
    for i in range(x):
        yield i*i

Using this generator:

>>> gen = squareOfSequence(5)
>>> for square in gen:
>>>     print(square)
0
1
4
9
16

Using Try-Except with Generators

Handle the end of a generator with exceptions:


gen = squareOfSequence(5)
while True:
    try:
        print('Received on next():', next(gen))
    except StopIteration:
        break

Generator Expressions

Python also offers a shorthand for creating generators called generator expressions. Here's a generator expression similar to squareOfSequence():

>>> squares = (x*x for x in range(5))
>>> for square in squares:
>>>     print(square)
0
1
4
9
16

Generator expressions are memory-efficient as they produce items one by one.

Conclusion

Generators in Python provide an efficient way to handle large data streams and complex iterables without consuming much memory. They allow defining iterators with less code and offer a powerful alternative to return-based functions.

Utilize Python generators to improve your code's efficiency and readability!