An iterator provides sequential access to collection elements while hiding how the collection stores them. It lets one algorithm process lists, generators, dictionaries, or other sequential collections through a common interface. section 11.0 section 11.1
The design problem appears when one report algorithm must process teams whose players are stored differently. Directly handling each representation couples the report to every team implementation and makes collection changes leak into client code. section 11.1 section 11.1.3
Refactor the design around a small iterator interface:
- Define next() to advance through the sequence and return the next domain object. section 11.1.3
- Define has_next() to report whether another object remains. section 11.1.3
- Implement a concrete iterator for each collection representation, such as ListIterator, GeneratorIterator, and DictionaryIterator. section 11.1.3 section 11.1.4
- Expose an iterator property from each team while keeping its player collection hidden. section 11.1.3
- Make the client use only the iterator interface: while it.has_next(), process it.next(). section 11.1.3
Player reports across three collections
Team 1 stores players in a list, Team 2 uses a generator, and Team 3 uses a dictionary. TeamReport obtains team.iterator and prints each Player without knowing which representation supplies it. Adding or replacing a sequential collection requires an appropriate iterator rather than changes to the report algorithm. section 11.1 section 11.4
Figure 11.3 Each Team subclass is paired with an Iterator class that is appropriate for its sequential collection of Player objects. Class TeamReport delegates iterating over the various types of sequential collections to the Iterator classes ListIterator, GeneratorIterator, and DictionaryIterator. The grayed-out portions of the diagram haven’t changed logically from figure 11.1.
Use the architecture diagram to trace the pairing between each Team subclass and its collection-specific iterator, then follow TeamReport’s delegated traversal. section 11.1.3
Python’s built-in iterators can be wrapped when polymorphism must select an iterator at runtime; the pattern is most useful when the client must remain independent of collection representations. section 11.1.4














