avatarIede Snoek

Summarize

Easy Python Patterns: The Iterator — Hacking With Python

Python iterators are powerful beasts, however did you know that you construct your own iterator over your own datastructures, so you can iterate just like you can or example over arrays? This article will show you how easy and convenient this is to implement in Python

Introduction

In Design Patterns, the Iterator is a way of traversing over a container, that is access each of the container’s elements. It is used as a convenient way to traverse over lists or arrays, but it could also be used to traverse over binary trees for example.

It looks like this:

A bit of explanation can be handy:

  1. An iterator basically has two methods: next() and hasNext()
  2. The next() method returns the next element in the container
  3. The hasNext() method returns a bool, true if a next element is available, false if there is no next element.

Implementation in Python

Like many modern languages, iterators are built into the language itself, lists and tuples for example can be iterated over. For our purpose we will build our own custom iterator, which just yields even numbers, up to a certain limit. You will see it will behave just like any other iterable type.

Since we want to return the type of the enclosing class, we need the following import:

from typing import Self

You will find an excellent article on this right here.

The EvenNumber iterator looks like this:

class EvenNumbers:
    _limit: int = None
    _current: int = None

    def __init__(self, limit: int):
        self._limit = limit
        self._current = 0

    def __iter__(self) -> Self:
        return self

    def __next__(self) -> int:
        self._current += 2
        if self._current <= self._limit:
            return self._current
        else:
            raise StopIteration

Some notes on this code:

  • In the constructor we set the starting value to 0, and we set a limit
  • The __iter__() method returns the iterator, in our case just self
  • In the __next__() method we return the next element in the sequence, if there is none, we raise a StopIteration exception and the iterator stops.

Using this iterator is almost ridiculously easy:

if __name__ == "__main__":
    for i in EvenNumbers(67):
        print(i, end=" ")

Here we just construct an object of the EvenNumbers class and set a limit. After that we simply iterate over the object, and all the method calls are done implicitly.

Conclusion

As you can see, as with many things in Python, it is very easy to build a simple iterator. My advice however would be that whenever you can, use Python’s built-in iterators.

One possible extension of this iterator would be to make it multi-threaded, but that will be the subject of another post. Also iterating over a somewhat more complicated datastructure would be an interesting application for this pattern, but that will also have to wait for another post.

Originally published at https://hackingwithpython.online on October 22, 2023.

Stackademic

Thank you for reading until the end. Before you go:

  • Please consider clapping and following the writer! 👏
  • Follow us on Twitter(X), LinkedIn, and YouTube.
  • Visit Stackademic.com to find out more about how we are democratizing free programming education around the world.
Python
Design Patterns
Design Pattern In Python
Iterator Pattern
Recommended from ReadMedium