Python Functions creating iterators for efficient looping

As in most programming languages Python provides while and for statements to form a looping construct. The for statement is especially useful to traverse the iterables like list, tuple or string. More efficient and fast iteration tools are defined in itertools module of Python’s standard library. These iterator building blocks are Pythonic implementations of similar tools in functional programming languages such as Haskell and SML.

Functions in itertools module are of three types.

  • Infinite iterators
  • Finite iterators
  • Combinatoric iterators

Following functions generate infinite sequences.

count() − This function returns an iterator of evenly spaced values from start value. The function can have optional step value to increment successive value by this interval.

>>> from itertools import count
>>> for x in count(20):
print (x)
>>> for x in count(100,10):
print (x)

First statement will generate infinite sequence starting from 20 and second will generate numbers from 100 with stepping frequency 10. Note that the loops are infinite and won’t terminate on their own. They will be terminated on pressing ctrl-C

cycle() − This function starts returning each element from given iterable and saves its copy. Once elements are exhausted, elements in saved copy are returned thereby forming infinite loop.

>>> from itertools import cycle
>>> for x in cycle("hello"):
print (x)

Characters in the string will be repetitively printed till keyboard interrupt Ctrl-C is issued.

repeat() − This function returns the object argument repeatedly. If second argument ‘times’ is provided, repetition takes place that many times.

>>> from itertools import repeat
>>> for x in repeat(1):
print (x)
>>> for x in repeat('hello', 10):
print (x)

First loop will print 1 endlessly. Second one prints 'hello' 10 times.

Functions in following category return finite iterators that terminate on shortest input sequence.

accumulate() − This function has two parameters. First is an iterable (list, tuple or string). Second parameter by default is operator.add() (function in operator module implementing standard addition operator), but may be any other function receiving two numeric parameters.

accumulate(sequence, func)

First two elements of input sequence are processed by func. Result of the process is first parameter for next iteration and second parameter to func is third element in input sequence. This process is repeated till the sequence is exhausted. The accumulate function returns an iterator in which each element is accumulated result of processing successive elements.

In following example, numbers in the list are cumulatively added. Note that default function argument is add operation.

>>> from itertools import accumulate
>>> list(accumulate([1,2,3,4,5]))
[1, 3, 6, 10, 15]

We can have a user defined function as second parameter to accumulate() function

>>> def multiply(x,y):
return x*y
>>> list(accumulate([1,2,3,4,5], multiply))
[1, 2, 6, 24, 120]

This behaviour is somewhat similar to built-in reduce() function. The reduce() function returns only the final result of accumulation, whereas accumulate() builds iterator of all intermediate results.

chain() − This function can have more than one iterables as parameter. It yields each element of first iterable into resultant iterator and proceeds to next until iterable parameters are exhausted.

>>> from itertools import chain
>>> list(chain([10,20],'hello',range(4)))
[10, 20, 'h', 'e', 'l', 'l', 'o', 0, 1, 2, 3]

dropwhile() − This function returns an iterator by dropping elements from terable as long as predicate function argument returns true. The moment the function returns false, all remaining elements are yielded to the iterator.

>>> from itertools import dropwhile
>>> def iseven(x):
if x % 2 == 0:
return True
return False
>>> list(dropwhile(iseven, [12,90,61,4,15]))
[61, 4, 15]

filterfalse() − This function returns an iterator by filtering out elements for whom the predicate function results False.

>>> from itertools import filterfalse
>>> def iseven(x):
if x % 2 == 0:
return True
return False
>>> list(filterfalse(iseven, [12,90,61,4,15]))
[61, 15]

islice() − This function build an iterator by selecting certain elements from iterable. The selection criteria depends on start, stop and step parameters. Selection starts from start value and continues till stop value. If stop is None, it goes upto end of iterable, otherwise selection stops at specified index. Step parameter is 1 by default. Selection of elements increments by step parameter. None of the parameters can be negative.

>>> from itertools import islice
>>> list(islice(range(10),1,5,2))
[1, 3]
>>> list(islice(range(10),0,None,3))
[0, 3, 6, 9]
>>> list(islice(range(10),5,None))
[5, 6, 7, 8, 9]
>>> list(islice(range(10),5))
[0, 1, 2, 3, 4]

Following function generate Combinatoric iterators from iterable objects.

product() − This function generates an iterator which is a Cartesian product of elements in input sequences. This is equivalent of constructing nested for loops, one for traversing each iterable sequence.

In following example list comprehension technique is used to run two nested loops on two sequences to build Cartesian product.

>>> [[x,y] for x in [1,2,3] for y in ['a','b','c']]
[[1, 'a'], [1, 'b'], [1, 'c'], [2, 'a'], [2, 'b'], [2, 'c'], [3, 'a'], [3, 'b'], [3, 'c']]

The product() function produces similar result

>>> from itertools import product
>>> list(product([1,2,3],['a','b','c']))
[(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), (3, 'a'), (3, 'b'), (3, 'c')]

permutations() − This function yields all possible permutations of elements in input iterable. Length of each permutation may be specified as second parameter to this function. If not specified, length is one.

>>> list(permutations(range(1,4),2))
[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]

combinations() − This function yields all possible combinations of elements in input iterable. Length of each permutation may be specified as second parameter to this function. If not specified, length is one.

>>> from itertools import combinations
>>> list(combinations(range(1,4),2))
[(1, 2), (1, 3), (2, 3)]

This article introduces various iterator tools defined in itertools module of Python library.