Practical Generator Patterns
Introduction to Generator Patterns
Generator patterns provide elegant solutions for complex data processing and iteration scenarios.
Data Processing Pipelines
def data_pipeline():
def extract(source):
for item in source:
yield item
def transform(data):
for item in data:
yield item.upper()
def load(data):
for item in data:
print(f"Processed: {item}")
source = ['apple', 'banana', 'cherry']
pipeline = load(transform(extract(source)))
list(pipeline)
Infinite Sequence Generators
def infinite_sequence():
num = 0
while True:
yield num
num += 1
## Controlled infinite generator
gen = infinite_sequence()
limited_seq = [next(gen) for _ in range(5)]
print(limited_seq) ## [0, 1, 2, 3, 4]
Generator Chaining
def generator_chain(*generators):
for gen in generators:
yield from gen
def gen1():
yield 1
yield 2
def gen2():
yield 3
yield 4
combined = list(generator_chain(gen1(), gen2()))
print(combined) ## [1, 2, 3, 4]
Coroutine-like Patterns
def coroutine_generator():
while True:
x = yield
print(f"Received: {x}")
def producer(consumer):
next(consumer) ## Prime the coroutine
for i in range(3):
consumer.send(i)
consumer = coroutine_generator()
producer(consumer)
Generator Pattern Strategies
graph TD
A[Generator Patterns] --> B[Data Processing]
A --> C[Infinite Sequences]
A --> D[Lazy Evaluation]
A --> E[Memory Efficiency]
Pattern |
Memory Usage |
Iteration Speed |
Complexity |
List Comprehension |
High |
Fast |
Low |
Generator Expression |
Low |
Lazy |
Medium |
Generator Function |
Low |
Lazy |
High |
Advanced Pattern: Recursive Generators
def recursive_generator(depth):
if depth > 0:
yield depth
yield from recursive_generator(depth - 1)
result = list(recursive_generator(3))
print(result) ## [3, 2, 1]
Error Handling Patterns
def safe_generator(data):
for item in data:
try:
yield int(item)
except ValueError:
print(f"Skipping invalid item: {item}")
data = [1, '2', 'three', 4, '5']
processed = list(safe_generator(data))
print(processed) ## [1, 2, 4, 5]
Real-world Use Cases
- Large File Processing
- Network Stream Handling
- Configuration Management
- Scientific Data Analysis
Best Practices
- Use generators for memory-intensive tasks
- Implement error handling
- Prefer generators over lists when possible
- Understand lazy evaluation benefits
LabEx recommends mastering these generator patterns for efficient Python programming.