Skip to content

Iterator

When using collections like list orset, in addition to adding or removing an item, we often want to perform certain operations on all of their items. Such collections store data differently, however, so as not to break the rules SOLID we should not give users the option to directly modify them.

In order to grant access to the elements of the collection, we use the Iterator pattern, which enables the so-called reiterate around the collection. Such an iterator should be able to:

  • taking the next item (next)
  • checking if there is another item (has_next)

In Python, iterator is part of the language.

Example

When creating an object that we want to iterate, we need to implement the iterable protocol, we need to:

  • create an iterator class with methods: __iter__ i __next__
  • create a method in our iterable class __iter__ returning iterator

The example below shows a class representing a sports team that can spell it after its players:

  • Class SportTeamIterator, knows the internal representation of a collection and implements the iterable protocol
  • Class SportTeam is a collection of objects that you can iterate over using a dedicated iterator
import string


class SportTeamIterator:
    def __init__(self, members):
        self._members = members
        self._idx = 0

    def __next__(self):
        if self._idx < len(self._members):
            val = self._members[self._idx]
            self._idx += 1
            return val
        else:
            raise StopIteration

    def __iter__(self):
        return self
class SportTeam:
    def __init__(self):
        self._members = []

    def add_member(self, name):
        if name.strip():
            self._members.append(string.capwords(name.strip()))

    def __iter__(self):
        return SportTeamIterator(self._members)
def main():
    sport_team = SportTeam()
    sport_team.add_member(' dudley stokes')
    sport_team.add_member('  devon harris')
    sport_team.add_member('michael white ')
    sport_team.add_member('  chris stokes')

    for member in sport_team:
        print(member)


if __name__ == '__main__':
    main()

The Iterator pattern is useful in a situation where we need to implement our own collections (which, given the high flexibility of Python, is rare) and be able to perform operations on their elements.