Python Iterator

Python Iterator

A Python Iterator is an object that can be iterated upon. Any kind of object that supports this kind of iteration is called as an iterator.

Now, you may be confused. There exists another object called iterable. What is that? Let’s take a look.


Iterators and Iterables

Any iterable is an object that can be iterated upon. That is, we can use iterators to move through this object.

Examples of Iterable objects are tuples, lists, strings, arrays, etc.

To construct an iterator from an iterable, we can use the iter() method.

iterable_list = [1, 2, 3]
iterable_string = "Hello"

iterator_1 = iter(iterable_list)
iterator_2 = iter(iterable_string)

print(iterator_1, type(iterator_1))
print(iterator_2, type(iterator_2))

Output

<list_iterator object at 0x7f887b01aed0> <class 'list_iterator'>
<str_iterator object at 0x7f887b01af50> <class 'str_iterator'>

The output shows that we have created two iterators; one for the list and one for the string.

Now let’s look at the methods which the iterator object supports.


Python Iterator Methods

An iterator object has two special methods that can be used with it, called iter() and next().

The iter() method was used earlier, to get a Python iterator object from an iterable.

Now, to traverse through the iterator, we can use the next() method to get the next element in the iterable.

Format:

next_iterable_object = next(iterator)

When there are no more elements left to go to, this will terminate and raise a StopIteration Exception.

To illustrate all this, let’s print all the elements of our list iterator.

>>> iterable_list = [1, 2, 3]
>>> iterator_1 = iter(iterable_list)
>>> next(iterator_1)
1
>>> next(iterator_1)
2
>>> next(iterator_1)
3
>>> next(iterator_1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

As you can see, when you go beyond the length of the iterable, this indeed raises the StopIteration Exception.

Now, let’s go to the next step: Making our own Iterator!


Constructing our own Iterator in Python

Any iterator object has a countable number of elements, that can be traversed. But how can we make our own iterator? We need to create our own Class.

In Python, constructing any iterator involves a protocol called the Iterator Protocol.

This protocol contains two specific methods, called __iter__() and __next__(), similar to the general iterator methods, but since they are inside a class, it is prefixed and suffixed with this symbol, to show the distinction.

The iter() and next() methods internally call these methods, and hence, to make the iterator, we need to define our own __iter__() and __next__() methods inside our class.

Let’s create a simple iterator that traverses across a list only and raises a StopIteration Exception if the count of elements is greater than 5.

We will also print the number of elements iterated so far, in our next() method.

class MyClass():
    def __init__(self):
        self.counter = 0
        # Set the limit
        self.limit = 5

    def __iter__(self):
        # The iter() method internally calls this
        print('Call to __iter__()')
        return self

    def __next__(self):
        print('Call to __next__()')
        if self.counter > self.limit:
            raise StopIteration
        else:
            # Increment counter and return it
            self.counter += 1
            return self.counter


# Create the iterable
my_obj = MyClass()

# Create the iterator object from the iterable
my_it = iter(my_obj)

for i in range(7):
    print(next(my_it))

Output

Call to __iter__()
Call to __next__()
1
Call to __next__()
2
Call to __next__()
3
Call to __next__()
4
Call to __next__()
5
Call to __next__()
6
Call to __next__()
Traceback (most recent call last):
  File "iter.py", line 29, in <module>
    print(next(my_it))
  File "iter.py", line 15, in __next__
    raise StopIteration
StopIteration

Here, this prints numbers from 1 to 6, and the next call will trigger the StopIteration exception, since we’ve crossed the limit.

We’ve made our own iterator!


Conclusion

I hope you now have a good understanding of iterators and any doubts regarding this concept are cleared after reading this article. If not, do ask them in the comment section below!


References

  • JournalDev article on Iterators