Practical Iterator Techniques
Advanced Iterator Manipulation
1. Generator Functions
Create memory-efficient iterators using generator functions:
def fibonacci_generator(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
## Convert generator to list
fib_list = list(fibonacci_generator(10))
print(fib_list)
2. Iterator Chaining
Combine multiple iterators seamlessly:
from itertools import chain
## Chaining multiple iterators
list1 = [1, 2, 3]
list2 = [4, 5, 6]
combined = list(chain(list1, list2))
print(combined) ## [1, 2, 3, 4, 5, 6]
Mapping and Filtering
## Transforming iterators
numbers = range(10)
squared_evens = list(map(lambda x: x**2, filter(lambda x: x % 2 == 0, numbers)))
print(squared_evens) ## [0, 4, 16, 36, 64]
Iterator Processing Strategies
Technique |
Use Case |
Memory Efficiency |
Generator |
Large datasets |
High |
List Comprehension |
Small to medium datasets |
Moderate |
map() and filter() |
Functional transformations |
High |
Infinite Iterators
from itertools import count, islice
## Creating and limiting infinite iterators
infinite_counter = count(10)
limited_counter = list(islice(infinite_counter, 5))
print(limited_counter) ## [10, 11, 12, 13, 14]
Iterator Flow Visualization
graph TD
A[Source Iterator] --> B{Transformation}
B -->|Map| C[Mapped Values]
B -->|Filter| D[Filtered Values]
B -->|Chain| E[Combined Iterator]
## Lazy evaluation for large datasets
def process_large_dataset(data_iterator):
return (item for item in data_iterator if complex_validation(item))
def complex_validation(item):
## Expensive computation
return len(str(item)) > 5
Error Handling and Iterator Management
def safe_iterator_conversion(iterator):
try:
return list(iterator)
except TypeError:
print("Cannot convert non-iterable object")
except MemoryError:
print("Iterator too large to convert")
Advanced Iteration Techniques
Zip and Enumerate
## Combining multiple iterators
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
combined_info = list(zip(names, ages))
print(combined_info) ## [('Alice', 25), ('Bob', 30), ('Charlie', 35)]
## Enumeration
enumerated = list(enumerate(names))
print(enumerated) ## [(0, 'Alice'), (1, 'Bob'), (2, 'Charlie')]
Best Practices
- Use generators for memory-efficient processing
- Leverage built-in iterator functions
- Implement lazy evaluation when possible
- Handle potential iterator exhaustion
- Choose appropriate conversion methods based on data size
Common Iterator Patterns
- Lazy evaluation
- Infinite sequences
- Data transformation
- Memory-efficient processing