Python generators

In Python, generators are a way to create iterators concisely and memory-efficiently. They are used to yield items one at a time, which is useful when working with large datasets or infinite sequences. Generators allow you to iterate over data without storing the entire sequence in memory.

Concepts

Generator Function: A function that uses the yield statement to return data one item at a time.

yield Statement: Similar to return, but instead of terminating the function, it pauses the function and saves its state. When the generator is called again, it resumes from where it left off.

Generator Expressions: Similar to list comprehensions, but they use parentheses instead of square brackets. They are a more memory-efficient way of creating sequences compared to list comprehensions.

Benefits of Using Generators

Memory Efficiency: Generators don’t store the entire sequence in memory; they generate items one at a time. This makes them ideal for handling large datasets or streaming data.

Lazy Evaluation: The values are generated only when needed. This is particularly useful in situations where generating all values at once would be wasteful or impossible.

Infinite Sequences: Generators can represent sequences with no end, like all even numbers or a sequence of random numbers.

Creating a Generator

A generator is created using a function with one or more yield statements.


def new_generator():
    yield 4
    yield 5
    yield 6

# Using the generator
gen = new_generator()
print(next(gen))  # Output: 4
print(next(gen))  # Output: 5
print(next(gen))  # Output: 6

When yield is encountered, the function pauses and returns the yielded value to the caller. When next() is called again, it resumes execution after the last yield statement.

Example: Generating a Sequence of Numbers

Here’s a generator that produces an infinite sequence of even numbers:


def evenNumbers():
    num = 0
    while True:
        yield num
        num += 2

# Using the generator
evens = evenNumbers()
print(next(evens))  # Output: 0
print(next(evens))  # Output: 2
print(next(evens))  # Output: 4

This generator will keep generating even numbers indefinitely, pausing each time it yields a value.

Generator Expressions

Generator expressions provide a quick and concise way to create generators. They look similar to list comprehensions but use parentheses instead of square brackets.

Example:


# List comprehension
squares_list = [x * x for x in range(10)]

# Generator expression
squares_gen = (x * x for x in range(10))

print(squares_list)   # Output: [0, 1, 4, 9, ..., 81]
print(next(squares_gen))  # Output: 0
print(next(squares_gen))  # Output: 1