Thursday, September 23, 2021

Python for Beginners: How to create an iterator in Python

Iterators are used to access the elements of an iterable object in a sequential manner. We can create an iterator for any container object such as a python dictionary, list, tuple, or a set. In this article, we will discuss how to create an iterator in python. We will also learn how to create custom iterators by overriding inbuilt methods.

Create iterator using inbuilt methods

We can create an iterator using the iter() function and the __next__() method. The iter() function takes a container object such as list, tuple, or set and returns an iterator with which we can access the elements of the container object.

To create an iterator for any container object using the iter() function, we just have to pass the object to the iter() function. The function creates an iterator and returns a reference to it. We can create an iterator using the iter() function as follows.

myList = [1, 2, 3, 4, 5, 6, 7]
myIter = iter(myList)
print("The list is:", myList)
print("The iterator is:", myIter)

Output:

The list is: [1, 2, 3, 4, 5, 6, 7]
The iterator is: <list_iterator object at 0x7f73fed18070>

In the output, you can observe that a list_iterator object has been created upon the execution of the iter() function.

How to access elements from an iterator?

To access the elements of the container object using iterators in a sequence, we can use a for loop as follows.

myList = [1, 2, 3, 4, 5, 6, 7]
myIter = iter(myList)
print("The list is:", myList)
print("The elements in the iterator are:")
for i in myIter:
    print(i)

Output:

The list is: [1, 2, 3, 4, 5, 6, 7]
The elements in the iterator are:
1
2
3
4
5
6
7

If you need to access the elements one by one, you can use the next() function or the __next() method. 

To traverse the iterator using next() function, we pass the iterator as an input argument to the function. It returns the next element in the iterator. The next() function also remembers the index at which the iterator had been traversed last time. When it is called again, it returns the next element which has not been traversed yet. This can be observed in the following example.

myList = [1, 2, 3, 4, 5, 6, 7]
myIter = iter(myList)
print("The list is:", myList)
print("The elements in the iterator are:")
element = next(myIter)
print(element)
element = next(myIter)
print(element)
element = next(myIter)
print(element)
element = next(myIter)
print(element)
element = next(myIter)
print(element)
element = next(myIter)
print(element)
element = next(myIter)
print(element)

Output:

The list is: [1, 2, 3, 4, 5, 6, 7]
The elements in the iterator are:
1
2
3
4
5
6
7

Process finished with exit code 0

The __next__() method works in a similar way as the next() function. Whenever the __next__() method is invoked on the iterator, it returns the next element that has not been traversed yet. 

myList = [1, 2, 3, 4, 5, 6, 7]
myIter = iter(myList)
print("The list is:", myList)
print("The elements in the iterator are:")
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)

Output:

The list is: [1, 2, 3, 4, 5, 6, 7]
The elements in the iterator are:
1
2
3
4
5
6
7

Process finished with exit code 0

When there is no element left for traversing and we use the next() function or the __next__() method, it raises the StopIteration exception.

myList = [1, 2, 3, 4, 5, 6, 7]
myIter = iter(myList)
print("The list is:", myList)
print("The elements in the iterator are:")
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)

Output:

Traceback (most recent call last):
  File "/home/aditya1117/PycharmProjects/pythonProject/webscraping.py", line 19, in <module>
    element = myIter.__next__()
StopIteration

It is advised to use these functions inside a python try except block to avoid the exception.

How to create a custom iterator in  Python

To create a custom iterator, we can override the __iter__() and __next__() methods that are set to default. We will understand how to create a custom iterator using the following example.

Suppose that you want to create an iterator that returns the square of each element of  a list or tuple when we iterate through the object using  the iterator. For this, we will override the __iter__() method and __next__() method. 

The constructor of the iterator will accept the list or tuple and the total number of elements in it. Then it will initialize the iterator class. As we need to keep track of the last element which was traversed, we will initialize an index field and set it to 0.

class SquareIterator:
    def __init__(self, data, noOfElements):
        self.data = data
        self.noOfElements = noOfElements
        self.count = 0

   

The __iter__() method is used to initialise an iterator. The __iter__() method is implemented as follows.

class SquareIterator:
    def __init__(self, data, noOfElements):
        self.data = data
        self.noOfElements = noOfElements
        self.count = 0

    def __iter__(self):
        return self

   

After overriding the __iter__() method, we will override the __next__() method. The __next__() method is used to traverse the next element that has not been traversed yet. Here, we need to return the square of the next element. 

As we have initialized the index to -1 in the __iter__() method, we will first increment the index. After that, we will return the square of the element at the specified index. Each time the __next__() method is invoked, the index will be incremented and the square of the element at the specified index will be given as output. When the number of traversed elements will equal the total number of elements in the list or tuple, we will raise the StopIteration exception. It will stop the iteration. The __next__() method can be defined as follows.

class SquareIterator:
    def __init__(self, data, noOfElements):
        self.data = data
        self.noOfElements = noOfElements
        self.count = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.count < self.noOfElements:
            square = self.data[self.count] ** 2
            self.count = self.count + 1
            return square
        else:
            raise StopIteration

The entire program to create the iterator is as follows.

class SquareIterator:
    def __init__(self, data, noOfElements):
        self.data = data
        self.noOfElements = noOfElements
        self.count = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.count < self.noOfElements:
            square = self.data[self.count] ** 2
            self.count = self.count + 1
            return square
        else:
            raise StopIteration


myList = [1, 2, 3, 4, 5, 6, 7]
myIter = SquareIterator(myList, 7)
print("The list is:", myList)
print("The elements in the iterator are:")
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)
element = myIter.__next__()
print(element)

Output:

The list is: [1, 2, 3, 4, 5, 6, 7]
The elements in the iterator are:
1
4
9
16
25
36
49

Process finished with exit code 0

Conclusion

In this article, we have studied two ways to create an iterator in Python. You can use custom iterators to perform different operations on the elements of a container object while traversing it. It is advised to implement some programs to create an iterator so that you can acquire a better understanding of the topic.

The post How to create an iterator in Python appeared first on PythonForBeginners.com.



from Planet Python
via read more

No comments:

Post a Comment

TestDriven.io: Working with Static and Media Files in Django

This article looks at how to work with static and media files in a Django project, locally and in production. from Planet Python via read...