How to Build a Basic Iterator in Python

In Python, iterators are powerful tools that allow you to traverse through a collection of values without needing to work directly with the underlying data structure. Whether you’re dealing with lists, sets, or even custom objects, understanding how to create your own iterator can be very beneficial.

In this blog post, we will discuss how to build a basic iterator using an example class called Example, and then we’ll explore a more straightforward implementation using a generator.

What is an Iterator?

An iterator is an object that conforms to the iterator protocol. This means it must provide two essential methods:

  1. __iter__(): This method returns the iterator object itself.
  2. __next__(): This method returns the next value from the collection. When there are no more items to return, it raises a StopIteration exception.

These methods facilitate the iteration over elements in a loop.

Creating a Basic Iterator

Let’s break down how to create an iterator step-by-step.

Step 1: Define the Class

We’ll begin by defining a class called Example. This class will take a list of values and expose them through the iterator.

class Example:
    def __init__(self, values):
        self.values = values

Step 2: Implement the Iterator Methods

Now, we will implement the __iter__ and __next__ methods in the Example class.

class Example:
    def __init__(self, values):
        self.values = values

    def __iter__(self):
        self.index = 0  # Initialize the index
        return self

    def __next__(self):
        if self.index < len(self.values):
            result = self.values[self.index]
            self.index += 1  # Move to the next index
            return result
        else:
            raise StopIteration  # No more values to return

Step 3: Use the Iterator

Now you can create an instance of Example and iterate through its values like this:

e = Example([1, 2, 3])
for value in e:
    print("The example object contains", value)

This code will produce the output:

The example object contains 1
The example object contains 2
The example object contains 3

Building a Counter Iterator

To further illustrate the concept, let’s build a simple Counter iterator that counts from a given low number to a high number.

Counter Class

Here’s how you can construct the Counter iterator:

class Counter:
    def __init__(self, low, high):
        self.current = low - 1
        self.high = high

    def __iter__(self):
        return self

    def __next__(self):
        self.current += 1
        if self.current < self.high:
            return self.current
        raise StopIteration

Using the Counter

You can use the Counter class like this:

for c in Counter(3, 9):
    print(c)

This will print:

3
4
5
6
7
8

An Alternative Approach: Using Generators

While the above iterator classes are useful, implementing a generator can be even simpler. Generators automatically handle the state and iteration protocol for you.

Here’s how you can create a counter as a generator:

def counter(low, high):
    current = low
    while current < high:
        yield current
        current += 1

for c in counter(3, 9):
    print(c)

The output remains the same, but the generator approach makes your code cleaner and easier to maintain.

Conclusion

Creating iterators in Python allows you to define your own looping behavior and manipulate how objects expose their values. By implementing the __iter__() and __next__() methods, you can provide a custom iteration experience. Additionally, using generators simplifies the process, saving time and reducing complexity.

For further reading on this topic, consider checking out David Mertz’s article on Iterators and Simple Generators.

Now that you have a basic understanding of how to create iterators in Python, you can begin to apply these concepts in your own projects!