Advanced Techniques
Generator Chaining and Composition
def generator_pipeline(data):
def filter_even(numbers):
return (num for num in numbers if num % 2 == 0)
def square_numbers(numbers):
return (num ** 2 for num in numbers)
return square_numbers(filter_even(data))
result = list(generator_pipeline(range(10)))
print(result) ## [0, 4, 16, 36, 64]
Coroutines and Generator-based Concurrency
flowchart LR
A[Generator] --> B[Coroutine]
B --> C[Asynchronous Processing]
Implementing Coroutines
def coroutine_example():
while True:
x = yield
print(f"Received: {x}")
## Coroutine usage
coro = coroutine_example()
next(coro) ## Prime the coroutine
coro.send(10)
coro.send(20)
Advanced Generator Techniques
Technique |
Description |
Use Case |
Send Method |
Two-way communication |
Interactive generators |
Throw Method |
Exception handling |
Error propagation |
Close Method |
Graceful termination |
Resource cleanup |
Generator Delegation with yield from
def subgenerator():
yield 1
yield 2
yield 3
def delegating_generator():
yield 'start'
yield from subgenerator()
yield 'end'
result = list(delegating_generator())
print(result) ## ['start', 1, 2, 3, 'end']
flowchart TD
A[Generator Optimization] --> B[Lazy Evaluation]
A --> C[Minimal Memory Footprint]
A --> D[Efficient Iteration]
Context Management with Generators
from contextlib import contextmanager
@contextmanager
def managed_generator():
print("Setup")
try:
yield
finally:
print("Cleanup")
with managed_generator():
print("Processing")
Advanced Use Cases
- Stream processing
- Large dataset manipulation
- Memory-constrained environments
- Functional programming patterns
At LabEx, we encourage exploring these advanced generator techniques to write more efficient and elegant Python code.
import timeit
def list_comprehension():
return [x**2 for x in range(1000)]
def generator_expression():
return (x**2 for x in range(1000))
## Compare performance
list_time = timeit.timeit(list_comprehension, number=10000)
gen_time = timeit.timeit(generator_expression, number=10000)
print(f"List Comprehension Time: {list_time}")
print(f"Generator Expression Time: {gen_time}")
Best Practices
- Use generators for large or infinite sequences
- Prefer generator expressions over list comprehensions
- Implement custom generators for complex iterations
- Understand memory and performance trade-offs