BlogsDope image BlogsDope

Python Iterators

April 23, 2019 PYTHON LOOP 397

By the name it is clear that iterators are used to iterate over something which is iterable. We use for loop to iterate over lists, tuples, etc. which itself implicitly implements iterator.

To make any iteration possible, we need three things:

  1. Initialize the iteration
  2. Produce the next value
  3. Stop the iteration

In Python, iterator is an object which implements __iter__() method which initializes an iterator by returning an iterator object and __next__() method which returns the next item in the process of iteration. Any iterator must implement these two methods and this is also called iterator protocol.

So, we can create an iterator and produce next elements using these two methods and we are left with the task to stop the iteration. We stop any iteration by raising StopIteration.

We will create our own iterator by implementing these methods but let’s first use iterator on lists, tuples and strings which already are iterables.

a = [1, 2, 3, 4, 5]

a_iterator = iter(a)

print(next(a_iterator))
print(next(a_iterator))
print(next(a_iterator))
print(next(a_iterator))
print(next(a_iterator))

1
2
3
4
5

Here, we have first made an iterator object using the iter(a) as discussed above. After this, we used next to get the elements in the sequence.

Strings are also iterable. Let’s see an example.

a = "Hello CodesDope"

a_iterator = iter(a)

print(next(a_iterator))
print(next(a_iterator))
print(next(a_iterator))
print(next(a_iterator))
print(next(a_iterator))

H
e
l
l
o

As stated above, for loop also uses iteration and that’s why we are able to directly use for loop on lists, tuples and strings. Let’s write a function similar to the for loop which will iterate through every element of a sequence.

def for_function(i):
    i_iterable = iter(i)

    while True:
        try:
            print(next(i_iterable))
        except StopIteration:
            break

for_function([1, 2, 3, 4])
for_function((1, 2, 3))
for_function("Hello CodesDope")

1
2
3
4
1
2
3
H
e
l
l
o

C
o
d
e
s
D
o
p
e

Here, we are first creating an iterable object with i_iterable = iter(i). Then we are running an infinite loop which will break at the end of the iteration - except StopIteration: → break. print(next(i_iterable)) is printing the value next in the sequence with each iteration of the while loop.

We have used pre-built iterators. Let’s write our own iterators.

Custom Iterator in Python


To make a iterator, we will create a class with two methods - __iter__() and __next__(). The __iter__() method will initialise the iteration and __next__() method will produce the next elements. Let’s look at an example.

class Increase:
    def __iter__(self):
        self.count = 0
        return self

    def __next__(self):
        x = self.count

        # each time after calling next, count increases by 1
        self.count = self.count+1

        # returning count
        return x

a = Increase()
a_iter = iter(a)
print(next(a_iter))
print(next(a_iter))
print(next(a_iter))
print(next(a_iter))
print(next(a_iter))

0
1
2
3
4

In the __iter__ method, we are making a variable count and setting it to 0 - self.count = 0 and at last, returning the object - return self.

So, a_iter = iter(a) gave us an object which is iterable with a variable count. Now, we can use the next method on this object and in our next method we are returning the value of the count. That’s why print(next(a_iter)) is printing the value of the variable count. And before returning the value, we are increasing the value of the count by 1 - self.count = self.count+1.

Since Increase is iterable, we can also use for loop on it.

class Increase:
    def __iter__(self):
        self.count = 0
        return self

    def __next__(self):
        x = self.count

        # each time after calling next, count increases by 1
        self.count = self.count+1

        # returning count
        return x

for i in Increase():
    print(i)

0
1
2
3
4
5
6
7

Let’s complete the discussion of iteration by stopping the iteration.

Stopping Iteration


As stated above, we stop an iteration by raising StopIteration.

class Increase:
    def __iter__(self):
        self.count = 0
        return self

    def __next__(self):
        if self.count <= 10:
            x = self.count

            # each time after calling next, count increases by 1
            self.count = self.count+1

            # returning count
            return x
        else:
            raise StopIteration

for i in Increase():
    print(i)

0
1
2
3
4
5
6
7
8
9
10


Liked the post?
Developer and founder of CodesDope.
Editor's Picks
0 COMMENT

Please login to view or add comment(s).