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.
Generators are a simple and powerful tool for creating iterators.
They are written like regular functions but use the yield statement whenever they want to return data.
Each time next() is called on it, the generator resumes where it left off (it remembers all the data values and which statement was last executed).
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