Python

Iterators in Python

An iterator is a valuable tool for Python. It is an object used to iterate all the elements of a collection. Iterator gives access to the elements of a container, but it does not do the iteration on its own. It works like a database cursor and is used to read the record list one by one. For example, a ‘for’ loop that iterates the values of a container works as an iterator. Python has many in-built iterators for iterable objects, such as lists, tuples, dictionaries, etc. Without these iterators, ‘itertools‘ functions can be used to return other iterators in Python. This article shows how to use the loop as an iterator, custom iterator, infinite iterator, and control infinite iterator in Python 3. Some uses of the ‘itertools’ functions are also explained in the last part of this tutorial.

Iterator Methods

Each iterator object contains the following two methods.

  • _ _iter_ _()

This method is used to initialize the iterable object. The returned object has the method ‘_ _next_ _()’ in Python 3.

  • _ _next_ _()

This method returns the next value of the iterable object. The relationship between the iterator and the iterable object is shown in the following diagram.

Iterating with Loops

It was mentioned earlier that the ‘for’ loop calls the ‘next()’ method implicitly when iterating any iterable object. When a loop is used for iterating an iterable object, the ‘for’ loop calls the ‘next()’ method implicitly and the ‘while’ loop calls the ‘next()’ or ‘__next__()’ method explicitly to read the next value of the iterable object. Both types of loop continue to call this method until the ‘StopIteration’ signal is generated.

Example 1: Iterating Iterable Objects with ‘for’ Loop

The following script shows the use of ‘for’ loops for iterating five different iterable objects. The first ‘for’ loop is used to iterate the string value and print each character of the string in each iteration. The second ‘for’ loop is used to iterate the content of an existing text file and print each line of the file in each iteration. The third ‘for’ loop is used to iterate the values of a tuple. The fourth ‘for’ loop is used to iterate the values contained in a list. The fifth ‘for’ loop is used to iterate the values contained in a dictionary.

# Iterating a String using for loop
print("String Iteration using for loop")    
str = "Python"
for val in str :
    print(val)

# Iterating an existing file using for loop
print("\n\nReading a file line by line using for loop")  
for line in open("test.txt"):
    print(line, end="")

# # Iterating a tuple using for loop
print("\n\nTuple Iteration using for loop")
tup = ("Book", "Paper", "Pencil", "Pen")
for val in tup:
    print(val)
   
# Iterating a list using for loop
print("\n\nList Iteration using for loop")
listdata = ["Designer", "Analyst", "Programmer","Administrator"]
for val in listdata:
    print(val)
     
     
# Iterating a dictionary using for loop
print("\n\nDictionary Iteration using for loop")    
dictval = {'Meher': 95, 'Sakib': 97, 'Akhi': 70, 'Fiaz': 78}
for index in dictval :
    print("%s achieved %d marks" %(index, dictval[index]))

Output

The following output shows that the characters of the string value; the lines of the test.txt file; and the items of the tuples, list, and dictionary are printed after running the script.

Example 2: Iterating Lists with ‘while’ Loop

The following script shows the use of a ‘while‘ loop for iterating a list of data. Here, the ‘iter()’ method is used to initialize the iterable object, and the ‘next()’ method is used to read the next value of the iterable object. StopIteration signal is used to terminate from the infinite ‘while’ loop when no item of the list left for reading.

# Define a list
listdata = ['google.com', 'bing.com','yahoo.com', 'baidu.com', 'duckduckgo.com']
# Initialize the iterable object
init_iter_object = iter(listdata)

print("Iterating List data using while loop:\n")

# Declare and infinite while loop  
while True:
    try:
        # next() method is used for iterate next value
        value = next(init_iter_object)
        print(value)
       
    except StopIteration:
        # Terminate from the loop after iterating all values
        break

Output

The following output shows that each value of the list has been printed in each line by using the ‘next()’ method after running the script.

Example 3: Iterating a Tuple with ‘__next__()’ Method and ‘while’ Loop

In the following script, both ‘next()’ and ‘__next__()’ methods are used for iterating the values of a tuple. The ‘iter()’ method is used to create the iterable object, named ‘init_iter.’ Here, the ‘next()’ method is called twice to print the first two values of the tuple. Next, an infinite ‘while’ loop is used to iterate the remaining values of the tuple and the ‘StopIteration’ signal is used to terminate from the loop, as in the previous example.

# define a tuple
animal_tuple =('Bird','Lion', 'Monkey', 'Snake', 'Elephant')

print("The values of the tuple are:\n")

# Initialize an iterator object using iter()
init_iter = iter(animal_tuple)
   
# iterate and print value using next() method
print(next(init_iter))
print(next(init_iter))
   
# Define an infinite while loop
while True:
    try:
        # iterate and print value using __next__() method
        print(init_iter.__next__())
       
    except StopIteration:
        # Terminate from the loop after iterating all values
        break

Output

The following output shows that after running the script, the first two values, ‘Bird’ and ‘Lion,’ are printed with the ‘next()’ method, while the other three values, ‘Monkey,’ ‘Snake,’ and ‘Elephant,’ are printed with the ‘__next__()’ method.

Iterating with a Custom Iterator

This section shows how different types of custom iterators can be implemented by creating classes. Both the ‘__iter__()’ and the ‘__next__()’ methods will be implemented in a class, and the ‘while’ loop will be used to iterate the values of the iterable object.  The next part of this article will also show how to create an infinite custom iterator and control the iteration.

Example 4: Use of a Simple Custom Iterator

The following script allows you to calculate the value of xn by using a custom iterator without using any built-in function of Python. The class named ‘x_to_the_power_n’ is declared in the script. The ‘__init__()’ method of the class will initialize the values of x and n that will be used at the time of object creation. The ‘__iter__()’ method will initialize the class variable, which will store the ‘result’ variable of the calculation in each iteration. The values of x and n will be taken as input from the user. An object of the class ‘numbers’ is created with x and n. Next, an iterable object named ‘iter_obj’ is created to call the ‘__next__()’ method for n-1 times by using the ‘while’ loop to calculate the value of xn. In each iteration, the value of x will be multiplied by the previous value of the ‘result’ variable. After terminating the ‘while’ loop, the ‘__next__()’ method will be called again to print the value of xn.

''' Create a class to calculate the
    x to the power n using iterator
'''

class x_to_the_power_n:

    # Initialize the value of x and n
    def __init__(self, x=0, n=0):
        self.x = x
        self.n = n
       
    # Initialize the iterable
    def __iter__(self):
        self.result = 1
        return self
   
    # Calculate the value in each iteration
    def __next__(self):
        if self.n >= 0:
            self.result *= self.x
            self.n -= 1
            return self.result
       
# Take the values of x and n
x = int(input("Enter the value of x: "))
n = int(input("Enter the value of n: "))

# Create an object of the class
numbers = x_to_the_power_n(x,n)

# Create an iterable
iter_obj = iter(numbers)
try:
    i = 0
    while(i < n-1):
       
        # Retrive the next value using next() method
        next(iter_obj)
        i+=1
       
    print("\n%d to the power %d is %d"  %(x,n,iter_obj.__next__()))
     
except StopIteration:
    # Terminate from the script if no value exists
    print(next(iter_obj))

Output

The following output shows that 2 is taken as the value of x and 4 is taken as the value of n. So, the script calculated the value of 2to be 16.

Example 5: Use of an Infinite Custom Iterator

The following script will continuously print the numbers that are divisible by 5 with a delay of one second until the user presses Ctrl + c to generate the ‘KeyboardInterrupt’ signal. The infinite ‘while’ loop is used here to create an infinite custom iterator. The ‘time’ module is imported at the beginning of the script to use the ‘sleep()’ method to delay each output for one second. The number 5 is initialized to the ‘num’ variable as the first divisible number in the script, and the next number is generated by adding 5 with the previous value of the ‘num’ variable.

# Import time module
import time

'''
Create a class to generate the numbers
which are divisible by 5 continuously
'''

class Number_Divisible_by_five:
 
  # Initialize the value of num
  def __iter__(self):
    self.num = 5
    return self
 
  # Calculate the next number which is divisible by 5
  def __next__(self):
    next_num = self.num
    time.sleep(1)
    self.num += 5
    return next_num

# Create an object of the class
Object = Number_Divisible_by_five()
# Create iterable object
iterObject = iter(Object)

# Define infinite loop
while True:
    try:
        # Go for next iteration
        print(iterObject.__next__())
    except KeyboardInterrupt:
        print("Ctrl+C is pressed.")
        # Terminate from the loop when Ctrl+C is pressed
        break

 

Output

The following output shows that the number started printing from 5 and continuously printed the next numbers one after another with a one-second duration. When the user pressed Ctrl + c after printing the number 60, the message ‘Ctrl+C is pressed.’ was printed, before terminating the script.

Example 6: Controlling A Custom Infinite Iterator

The following script shows how to stop the custom infinite iterator after completing a specified number of iterations. The ‘__iter__()’ method of the class will initialize the values of the ‘n’ and ‘result’ class variables. The script will calculate the squares of the numbers, starting from 1, that are stored in the variable n, and print the square value of n until the value of n is greater than 5. An infinite while loop is declared here to call the ‘__next__()’ method to print the square value of n. When the value of n reaches 6, the ‘StopIteration’ signal will generate to terminate the loop.

# Import time module
import time

'''
Create a class to calculate
the square of the number starts from 1 until
the value of the number is less than 6
'''

class calculate_power:
 
  # Initialize the value of num
  def __iter__(self):
    self.n = 1
    self.result=0
    return self
 
  # Calculate the next number which is divisible by 5
  def __next__(self):
    # Check the value of n is less than or equal to 5 or not
    if self.n <= 5:
       self.result = self.n**2
       time.sleep(0.5)
       self.n += 1
       return self.result
    else:
      raise StopIteration

# Create an object of the class
Object = calculate_power()
# Create iterable object
iterObject = iter(Object)

# Define infinite loop
while True:
    try:
        # Go for the next iteration and print the square value
        print("The square of %d is %d" %(iterObject.n,iterObject.__next__()))
    except StopIteration:
        print("\nTerminated from the loop.")
        # Terminate from the loop
        break

Output

The following output shows that the infinite custom iterator was terminated when the value of n became greater than 5. The script calculated and printed the square values of the number values from 1 to 5.

Iterating with itertools

Python has a built-in module named ‘itertools‘ that can be used to create an iterator for iterating data using a loop. The next section of this article shows how to use three functions in this module.

itertools.count()

The ‘itertools.cont’ function can be used with the ‘map()’ method to generate sequential data and with the ‘zip()’ method to add sequences by using the count parameter of this method. The syntax of this function is given below.

Syntax

itertools.count(start=0, step=1)

Here, the first parameter, ‘start,’ is used to define the starting value of the sequence, and 0 is the default value of this parameter. The second parameter, ‘step,’ is used to set the difference between the consecutive numbers, and 1 is the default value of this parameter.

Example 7: Use of count() Function of itertools

The following script will calculate the sum from 0 to n numbers, where the value of n will be taken from the user. The ‘count()’ function is imported from ‘itertools’ at the beginning of the script. The ‘my_iterator’ object is initialized with the ‘count()’ function, with a ‘start’ value of 0 and a ‘step’ value of 1. Next, the ‘sum_result’ variable is initialized by the first value of the iterable object. The starting value is initialized to the variable i and the starting number is stored as the character in the variable, numbers that will be used to combine other numbers in each iteration. The values of the sequential numbers will be added in each iteration when the ‘next()’ method is called. When the value of i becomes greater than n, the script will terminate by displaying the result of the sum.

''' The following script will calculate
the sum of 0 to the number that will be taken as input.
'''

# Import count
from itertools import count

# Creates an iterable object of count()
my_iterator = count(start=0, step=1)
# Read the first value from the iterator
sum_result = next(my_iterator)

# Take a number input to terminate the infinite while loop
n = int(input("Enter the limit value:"))

# Initialize the value of i and numbers
i = sum_result
numbers = f'{i}'

# Declare infinite loop
while True:
    # Add the number in each iteration
    sum_result += i
    i = next(my_iterator)
    # Terminate the loop if the value of i is more than n
    if(i > n):
        break
    # Add the number value as a string with '+' symbol
    numbers += "+" + f'{i}'
   
# Print the final value
print("%s = %d" % (numbers,sum_result))

Output

The following output shows that the number 10 is taken as the input used for terminating the loop after running the script. In this output, the script has calculated the sum from 0 to 10 and printed the output, 0+1+2+3+4+5+6+7+8+9+10 = 55.

Itertools.cycle()

This function contains only one argument, which can be any object. The purpose of this function is to repeat the values of the object after completing the iteration of all values. Here, strings, tuples, lists, etc. can be used as an object. The iterable object returns of this function are used to iterate each value of the object that will be used as an argument by using the ‘next()’ method. The number of times the values of the iterable object will iterate will be based on the number of iterations of the loop. The syntax of this function is given below.

Syntax

itertools.cycle(Object)

Example 8: Use of cycle() Function of itertools

The ‘random’ and ‘itertools’ modules are imported at the start of the script to generate a random number and to use the ‘cycle()’ function from the  ‘itertools’ module for repeating the data. A list of three random numbers is used as the argument of the ‘cycle()’ function. The iterable object named ‘num_list’ is initialized by the return value of this function. The ‘count’ variable is initialized to 0, and when the value of this variable becomes 6, the ‘while’ loop will terminate. So, the ‘while’ loop will iterate six times, and each value of the list will repeat only one time.

# Import random module
import random

# Import itertools module
import itertools

# Generate an iterable object based on the list of three random numbers
num_list = itertools.cycle([random.randint(1,5),random.randint(10,50),random.randint
(100,500)] )

# Initialize the counter
count = 0

# Iterate the loop for 6 times
while(count != 6):
    print('The current random number is: ' + f'{next(num_list)}')
    count+=1

Output

The following output shows that three random numbers, 3, 17, and 185, have been generated as list items. The loop is iterated six times, and these three values are repeated for the next iterations.

Itertools.repeat()

The ‘repeat()’ function works like an infinite iterator and can take two arguments. When the second argument is omitted, the ‘repeat()’ function works as an infinite iterator and repeats the value an infinite number of times. This function does not occupy memory for each repeat. It just creates the variable one time in the memory and repeats the same variable an infinite number of times when only one argument is set for this function. The syntax of this function is given below.

Syntax

itertools.repeat(value, limit)

The first argument is used to take the value that will repeat. The second argument is optional and is used to set the limit of repeats.

Example 9: Use of repeat() Function of itertools Module

The ‘itertools’ module is imported at the start of the script to use the ‘repeat()’ function. A string value will be taken from the user to repeat, and a number value will be taken from the user to set the repeat limit. The return value of the ‘repeat()’ function will then be converted into a list with the ‘list()’ method and stored in the ‘listData’ variable. The values of the ‘listData’ will be printed with the ‘for’ loop.

# Import itertools module
import itertools    

# Take the input value that will repeat
string = input("Enter a string: ")
# Take the number value to repeat
repeat = int(input("Enter the number to repeat: "))

# using repeat() to repeatedly add the string into a list    
listData= list(itertools.repeat(string, repeat))

# Initilize i
i = 1
print ("The list values are : \n")
# Iterate the list using for loop  
for val in listData:
    print("List item %d =%s" %(i,val))
    i += 1

Output

The following output shows that ‘Python’ is taken as the string value, and 3 is taken as the number used to repeat the string value after running the script. The output shows that the string ‘Python’ is repeated three times.

Conclusion

The concept of iterator and the uses of different types of iterators in Python are tried to explain with the very simple examples in this article. Python users can use a built-in iterator or can create their custom iterator based on the requirement. This article will help the python users to know about the methods used in the iterator and how these methods work with any loop to read any iterable object. Some uses of itertools module of python are also explained in this article to know more details of the iterator in python.

About the author

Fahmida Yesmin

Fahmida Yesmin

I am a trainer of web programming courses. I like to write article or tutorial on various IT topics. I have a YouTube channel where many types of tutorials based on Ubuntu, Windows, Word, Excel, WordPress, Magento, Laravel etc. are published: Tutorials4u Help.