Learnerslesson
   JAVA   
  SPRING  
  SPRINGBOOT  
 HIBERNATE 
  HADOOP  
   HIVE   
   ALGORITHMS   
   PYTHON   
   GO   
   KOTLIN   
   C#   
   RUBY   
   C++   




PYTHON - ITERATORS


So far we have seen, how to Iterate through a Collection(i.e. List, set, tuple e.t.c) using a 'for' loop.


Example :


the_list = [1, 3, 5, 8]
for i in the_list:
    print(i)


Output :



  1
  3
  5
  8

Now, there is another way by which we can Iterate a Collection(i.e. List, set, tuple e.t.c) or even a String. And that is an Iterator.


An Iterator is a Python object that is used to Iterate a Collection or a String.


To understand Iterator, let us rewrite the above example with Iterator.


Example :


the_list = [1, 3, 5, 8]
the_iter = iter(the_list)
print(next(the_iter))
print(next(the_iter))
print(next(the_iter))
print(next(the_iter))


Output :



  1
  3
  5
  8

So, in the above code, what we have done is, created a list named, 'the_list'.


the_list = [1, 3, 5, 8]

And created an Iterator object named 'the_iter'.


the_iter = iter(the_list)

This is the way we create an Iterator object. Pass the list, 'the_list' to the 'iter(...)' method and an Iterator object is created by Python.


Python - Iterators

Now, we have the Iterator object 'the_iter' and all the values of the List is in the Iterator object 'the_iter'.


The next task would be get the values of the List, 'the_list'.


And the iterator object has a method has a method called 'next( )', that would get the values of the iterator, one by one.


So, the first 'next(the_iter)' method


print(next(the_iter))

Prints the first element of the Iterator object 'the_iter'.


1

Similarly, the second 'next(the_iter)' method


print(next(the_iter))

Prints the second element of the 'the_iter'.


And so on.


Similarly, we can print the elements of the String in the same way.


Example :


the_string = "Hello"
the_iter = iter(the_string)
print(next(the_iter))
print(next(the_iter))
print(next(the_iter))
print(next(the_iter))
print(next(the_iter))


Output :



  H
  e
  l
  l
  o

So, the same way, all the elements of the String is printed.


Now, let us say, we want to create a custom Iterator object. Let's see that next.


Creating a Custom Iterator object


Creating a Custom Iterator object can be done by redefining the methods '__iter__( )' and '__next__( )'.


Now, let us say, we want to create Iterator object that prints the numbers 1 to 5.


Let us see in the next example.


Example :


class CustomIterator:
    def __iter__(self):
        self.x = 0
        return self
	
    def __next__(self):
        self.x = self.x + 1
        return self.x

the_object = CustomIterator()
the_iter = iter(the_object)

print(next(the_iter))
print(next(the_iter))
print(next(the_iter))
print(next(the_iter))
print(next(the_iter))


Output :



  1
  2
  3
  4
  5

So, in the above code, all we have done is, created a class named 'CustomIterator' and defined the methods '__iter__( )' and '__next__( )' in it.


class CustomIterator:
    def __iter__(self):
        self.x = 0
        return self
	
    def __next__(self):
        self.x = self.x + 1
        return self.x

So, at first, we create the object of 'CustomIterator' class.


the_object = CustomIterator( )

Then, we pass the object, the_object of the 'CustomIterator' class to the 'iter( )' method to create an Iterator object.


the_iter = iter(the_object)

So, Python goes to the class 'CustomIterator' and finds the 'def __iter__(self):'. So, Python understands that an object of Iterator Type needs to be created.


So, in the 'def __iter__(self):' method,


def __iter__(self):
    self.x = 0
    return self

We have initialised the value of 'x' with '0'.


self.x = 0

And when we return 'self', it is a Iterator object that is returned.


the_iter = iter(the_object)

And 'the_iter' is an Iterator object now.


So, we can call 'next( )' method on 'the_iter'. And that's exactly what we have done in the next line.


print(next(the_iter))

And the 'def __next__(self):' method of 'CustomIterator' class is called.


def __next__(self):
    self.x = self.x + 1
    return self.x

And this is where, the value of 'x' is incremented. And each 'next(the_iter)' prints the incremented value one by one.


How to use while loop with Iterator?


Sometimes you might be feeling, it's a pain to call the 'next( )' method every time to print the elements.


Would be a lot better if we could loop through it.


And that is what we will be seeing next.


Example :


the_list = [1, 3, 5, 8]
the_iter = iter(the_list)
while(True):
    try:
        print(next(the_iter))
    except StopIteration:
        print("Loop Ended")
        break


Output :



  1
  3
  5
  8

So, to use a loop in Iterator, there are some things we need to know. i.e. If the 'next( )' method comes to the end of List, it raises an Exception.


And that's exactly why we have used the 'try' block inside the 'while' loop.


while(True):
    try:
        print(next(the_iter))
    except StopIteration:
        print("Loop Ended")
        break

So that whenever the 'next( )' method comes to the end of the List, it would raise an exception called 'StopIteration'.


except StopIteration:

And that's when we break out of the loop using the 'break' statement.