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
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))
<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().
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.
next_iterable_object = next(iterator)
When there are no more elements left to go to, this will terminate and raise a
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
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
__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.
next() methods internally call these methods, and hence, to make the iterator, we need to define our own
__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
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))
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!
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!
- JournalDev article on Iterators