Custom Iterators
Custom Iterators in Python
While Python provides built-in iterators for sequences and collections, writing your own Custom Iterators allows you to stream complex data structures, generate custom mathematical sequences, and traverse domain models cleanly using Python's native for loop syntax.
1. Creating a Basic Custom Iterator
To create a custom iterator class, implement two essential methods:
- 1
__iter__(self): Returns the iterator instance (typicallyreturn self). - 2
__next__(self): Calculates and returns the next element, or raisesStopIterationwhen the sequence is completed.
Example 1: A Custom Countdown Iterator
2. Re-creating the range() Function
Here is how Python's built-in range() can be implemented from first principles:
3. Stateful Mathematical Sequence: Fibonacci Iterator
Custom iterators can maintain complex state across iterations without keeping every generated number in memory:
4. Re-usable Iterables: Separating Iterable from Iterator
When a class combines __iter__ and __next__ in one object, it is consumed after a single pass and cannot be re-iterated without re-instantiation.
To build an iterable collection that can be looped over multiple times (like a list), separate the Collection (Iterable) from the Iterator:
5. Common Pitfalls
- Forgetting
StopIteration: If your__next__method never raisesStopIteration, loops over the iterator become infinite loops. - Forgetting
return self: An iterator's__iter__method must return an iterator object, typicallyself. - Modifying the underlying collection during iteration: Adding or removing elements from a list while iterating over it leads to skipped elements or index bugs.
Multiple Choice Questions
1. What two methods must a custom iterator class implement to satisfy the Python Iterator Protocol?
A. __init__() and __del__() B. __iter__() and __next__() C. __start__() and __step__() D. __enter__() and __exit__() Answer: B Explanation: The Iterator Protocol requires __iter__() (which returns the iterator) and __next__() (which returns consecutive items and raises StopIteration).
2. Why should the __iter__() method of an iterator class return self?
A. To prevent Python's garbage collector from deleting the object B. So that the iterator itself can be used anywhere an iterable is expected (e.g. in for loops) C. To force the class to run in a single thread D. To clone the object in memory Answer: B Explanation: Python expects iterators to be iterables as well; returning self in __iter__() allows an iterator to be passed directly to for loops and built-in functions like sum().
3. What happens if a custom iterator's __next__() method never raises StopIteration?
A. The iterator will raise a SyntaxError B. Any standard for loop consuming it will continue indefinitely as an infinite loop C. Python terminates the loop after 1000 cycles D. Memory is automatically cleared Answer: B Explanation: Python relies exclusively on StopIteration to detect the end of iteration. Without it, the loop will run endlessly until interrupted.
4. How can you make a custom collection class re-iterable across multiple distinct for loops?
A. By placing return self in both __iter__ and __next__ B. By having __iter__() return a new, distinct iterator instance every time it is called C. By making all attributes static D. By calling del self at the end of __next__ Answer: B Explanation: To allow repeated iterations, the collection's __iter__() method must instantiate and return a fresh iterator object initialized at the beginning of the sequence.
5. What error is raised by StepRange if the step argument provided is 0?
A. ZeroDivisionError B. ValueError C. IndexError D. StopIteration Answer: B Explanation: In both Python's built-in range() and custom range implementations, a step of 0 is mathematically invalid and raises a ValueError.
Using Generators with yield
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
| Previous Lesson | Next Lesson |
|---|---|
| Understanding Iterators | Using Generators with yield |
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.