Infinite Iterators in Python
An iterator is an object that enables one to traverse a container. It is used in ‘for in loop’. Iterator and iterable are two objects which work behind the mechanism of ‘for’ loop. Python iterators are objects used with looping.
List, tuple, sets, and dictionary are some of the examples of in-built iterators.
# from for loop
num = [1,2,3,4] for i in range(len(num)): print(num[i]) Output: 1 2 3 4
# from iter() and next() function
num=[1,2,3,4] iter_func=iter(num) print(next(iter_func)) print(next(iter_func)) print(next(iter_func)) print(next(iter_func)) Output: 1 2 3 4
The iterator object is finite in the above example. However, there are infinite iterator objects as well known as the Infinite Iterator.
Python itertools package provides various functions to work with iterators. Itertools provide a core set of fast and memory efficient tools.
Let us gather a deep understanding of this topic using simple python programs.
This package provides three types of infinite iterator:
1. Count(start=0, step=1):
Method 1: using the break statement.
The count iterator prints the value from the start value to infinite. This function takes as argument a start value and a step value. The default value of the step is 1 which is modifiable. Mentioning the steps skips the values from the series equal to the number of steps. Steps specify the difference between two values.
Syntax – count(start, step)
start is the starting value.
step defines the difference between two consecutive numbers(default = 1).
Refer to the two examples below for the use of count iterator.
- The start value is 0 in the first code below and the loop continues by printing all values starting from 0 till 5. As no value for step is specified therefore the default step value is 1. The loop breaks on encountering values greater than 5 due to the presence of break statement else it would have run infinitely.
- The start value is 10 in the second code below and the loop continues by printing all values starting from 10 till 20. As value for step is 2 in this example, all even numbers between 10 to 20 are printed. The loop breaks on encountering values greater than 20 due to the presence of break statement else it would have run infinitely.
# infinite iterator # import count from itertools package from itertools import count # step is not defined for num in count(0): if num > 5: break else: print(num)
Output: 0 1 2 3 4 5
# infinite iterator # if steps are defined: for num in count(10,2): if num > 20: break else: print(num)
Output: 10 12 14 16 18 20
Method 2: limit using islice iterator:
islice iterator from the Python itertools package works for limiting the infinite iterator. It takes any object that generates a sequence of outputs and a limit to stop that iteration. islice stops the infinite iterator on the value mentioned by the user. It takes as argument an infinite iterator and a stop value. The islice iterator selectively iterates till the nth term passed as an argument in the islice container beginning from from a start position.
Syntax: islice(iterable, start, stop, step)
iterable is the object to operate upon.
start and stop refer to the starting and ending values respectively
step refers to the difference between two consecutive values(default step=1)
The below code takes count(5) as the iterable and 3 is the limit to islice. Values starting from 5 are printed till 3 values i.e. 7
infinite iterator # import islice iterator from the itertools package from itertools import count from itertools import islice for num in islice(count(5), 3): print(num)
Output: 5 6 7
cycle iterator works in a cyclic manner. It sequentially prints all the elements passed in the cycle container till the last element. It restarts printing all elements from the beginning again after the completion of each cycle. This cycle continues infinitely if no limit is used. A sequence of first element to last is generated each time a cycle runs.
This function takes only one argument as input be it list, string, tuple etc.
input can be any list, tuple or string
#infinite iterator # import cycle from the itertools package from itertools import cycle # value of i is index from where the iteration have to start i = 0 for element in cycle('CS'): if i > 5: break print(element) i += 1
Output: C S C S C S
Through cycle iterator, ‘CS’ can be printed infinite times if no limit is specified. However, here, we limit the cycle by specifying the break statement. A continuous sequence of ‘CS’ is generated three times in a cyclic manner. The iteration stops when the loop breaks at index of 5 starting from the 0th position.
Method 2: Using the next function of iterators.
The next() built-in function iterates over the iterators. It gets the next result from an iterator.
iterators refer to the object on which next() operates.
Refer to the example below to have a look at the working of the next() function. The pointer initially points at the first element of the list and traverse through the entire list after encountering the next() function every time. It prints the first element and then moves to the next element in the list. Here, the next() function is called 8 times which ends up printing all the elements of the list twice.
# infinite iterator import itertools l = ['code','speedy','infinite','iterator'] element = cycle(l) for val in range(8): print(next(element))
Output: code speedy infinite iterator code speedy infinite iterator
3. repeat(value, num_times):
In repeat(), we specify the value and a number which decides on the number of times the value to repeat. The repeat iterator creates infinite copies of the element passed in the repeat container. However, there is an option to limit the repeat iterator too. By specifying the second argument in the repeat container which is a stop value. It prints the copy of the element as many times as the stop value.
Syntax: repeat(value, num_times)
value – prints the value specified.
num_times – refers to the number of times the specified value should repeat.
# infinite iteration # import repeat from itertools package from itertools import repeat number = repeat(1, 5) for value in range(5): print(next(number))
Output: 1 1 1
StopIteration Traceback (most recent call last) <ipython-input-18-e0cd785fb735> in <module> 5 number = repeat(1, 3) 6 for value in range(4): ----> 7 print(next(number))
Repeat iterator iterates until the number of copies of the element gets equivalent to the second argument of the repeat iterator. In the above example, it iterates till 3rd iteration rendering three copies of value =1. The Stop Iteration exception occurs on printing the element repeatedly as many times as specified. The Stop Iteration error here occurred after printing 1 thrice i.e on the 3rd iteration.