Exhaustion Pitfalls
Understanding Iterator Exhaustion
Iterator exhaustion occurs when all elements of an iterator have been consumed, and no more elements remain. Once exhausted, an iterator cannot be reused without recreation.
Common Exhaustion Scenarios
## Demonstration of iterator exhaustion
def simple_iterator():
yield from [1, 2, 3]
## Scenario 1: Single Iteration
iterator = simple_iterator()
print(list(iterator)) ## [1, 2, 3]
print(list(iterator)) ## [] - Empty list
## Scenario 2: Multiple Consumption Attempts
def problematic_iteration():
numbers = [1, 2, 3]
iterator = iter(numbers)
## First consumption
print(list(iterator)) ## [1, 2, 3]
## Second attempt - no elements left
try:
print(list(iterator)) ## Raises StopIteration
except StopIteration:
print("Iterator exhausted!")
Exhaustion Patterns and Risks
Scenario |
Risk |
Mitigation |
Single Pass Iteration |
Data Loss |
Create Copy/Regenerate |
Multiple Consumers |
Incomplete Processing |
Use itertools.tee() |
Long-Running Generators |
Memory Consumption |
Implement Lazy Evaluation |
Advanced Exhaustion Handling
import itertools
## Safe Iterator Replication
def safe_iterator_usage():
original = iter([1, 2, 3, 4])
## Create multiple independent iterators
iterator1, iterator2 = itertools.tee(original)
print(list(iterator1)) ## [1, 2, 3, 4]
print(list(iterator2)) ## [1, 2, 3, 4]
## Generator with Controlled Exhaustion
def controlled_generator(max_items):
count = 0
while count < max_items:
yield count
count += 1
## Demonstrating Controlled Iteration
gen = controlled_generator(3)
print(list(gen)) ## [0, 1, 2]
Exhaustion Visualization
graph TD
A[Iterator Created] --> B{Elements Available?}
B -->|Yes| C[Consume Element]
C --> B
B -->|No| D[Iterator Exhausted]
D --> E[Raise StopIteration]
Best Practices
- Always assume iterators are single-use
- Create copies when multiple iterations are needed
- Use
itertools.tee()
for safe iterator replication
- Implement lazy evaluation for memory efficiency
LabEx Recommendation
LabEx suggests treating iterators as disposable resources and designing code that anticipates potential exhaustion scenarios.