Advanced Python Made Easy — Part 4
By: Naina Chaturvedi
Tags: Python, Machine Learning, Data Science, Programming, Software Development

This is the part 4 of Advanced Python Made Easy. You can refer to the first three parts here —

Today in this post we are going to take a deep dive in Python’s Itertools.

Let’s dive in !

Itertools

Python Itertools are fast, memory efficient functions— a collection of constructs for handling iterators. Iterators are nothing but an object that contains a countable number of value i.e values you can traverse through and can be Infinite iterators, Combinatoric iterators, Terminating iterators. List, tuples, dictionaries, and sets are all iterable objects.

To create an object as an iterator you have to implement the methods __iter__() and __next__() to your object,

where —

__iter__() returns the iterator object itself. This is used in for and in statements.

__next__() method returns the next value in the sequence. In order to avoid the iteration to go on forever, raise the StopIteration exception.

Implementation of itertools functions —

i) combinations()

Syntax —

itertools.combinations (iterable, r)

Code —

import itertools

countries = ['USA', 'Australia', 'Canada','Germany']

result = itertools.combinations(countries, 3)

for i in result:

print(i)

Output —

('USA', 'Australia', 'Canada')

('USA', 'Australia', 'Germany')

('USA', 'Canada', 'Germany')

('Australia', 'Canada', 'Germany')

ii) combinations_with_replacement ()

It allows the element repetition.

Syntax —

itertools.combinations_with_replacement (iterable, r)

Code —

import itertools

countries = ['USA', 'Australia', 'Canada','Germany']

result = itertools.combinations_with_replacement(countries, 3)

for i in result:

print(i)

Output —

('USA', 'USA', 'USA')

('USA', 'USA', 'Australia')

('USA', 'USA', 'Canada')

('USA', 'USA', 'Germany')

('USA', 'Australia', 'Australia')

('USA', 'Australia', 'Canada')

('USA', 'Australia', 'Germany')

('USA', 'Canada', 'Canada')

('USA', 'Canada', 'Germany')

('USA', 'Germany', 'Germany')

('Australia', 'Australia', 'Australia')

('Australia', 'Australia', 'Canada')

('Australia', 'Australia', 'Germany')

('Australia', 'Canada', 'Canada')

('Australia', 'Canada', 'Germany')

('Australia', 'Germany', 'Germany')

('Canada', 'Canada', 'Canada')

('Canada', 'Canada', 'Germany')

('Canada', 'Germany', 'Germany')

('Germany', 'Germany', 'Germany')

iii) count ()

Syntax —

itertools.count (start, step)

Makes an iterator that returns evenly spaced values starting with number specified with start.

Code —

import itertools

for i in itertools.count(20,4):

print(i)

if i > 30:

break

Output —

20

24

28

32

iv) groupby()

To group things together just like in SQL.

Syntax —

itertools.groupby (iterable, key=None)

Code —

import itertools



countries = [("West", "USA"),

("West", "Canada"),

("East", "Singapore"),

("East", "China")]



iterator_one = itertools.groupby(countries, lambda x : x[0])



for key, group in iterator_one:

result = {key : list(group)}

print(result)

Output —

{'West': [('West', 'USA'), ('West', 'Canada')]}

{'East': [('East', 'Singapore'), ('East', 'China')]}

v)permutations()

Syntax —

itertools.permutations (iterable, r=None)

Code —

from itertools import permutations name = "Adam"



result = permutations(name)



for j in list(result):

print(j)

Output —

('A', 'd', 'a', 'm')

('A', 'd', 'm', 'a')

('A', 'a', 'd', 'm')

('A', 'a', 'm', 'd')

('A', 'm', 'd', 'a')

('A', 'm', 'a', 'd')

('d', 'A', 'a', 'm')

('d', 'A', 'm', 'a')

('d', 'a', 'A', 'm')

('d', 'a', 'm', 'A')

('d', 'm', 'A', 'a')

('d', 'm', 'a', 'A')

('a', 'A', 'd', 'm')

('a', 'A', 'm', 'd')

('a', 'd', 'A', 'm')

('a', 'd', 'm', 'A')

('a', 'm', 'A', 'd')

('a', 'm', 'd', 'A')

('m', 'A', 'd', 'a')

('m', 'A', 'a', 'd')

('m', 'd', 'A', 'a')

('m', 'd', 'a', 'A')

('m', 'a', 'A', 'd')

('m', 'a', 'd', 'A')

vi) product()

It gives the Cartesian product of the input iterables.

Syntax —

itertools.product (*iterables, repeat=1)

Code —

from itertools import product



def cart_product(arr1, arr2):



return list(product(arr1, arr2))



arr1 = [100, 200]

arr2 = [500, 600]

print(cart_product(arr1, arr2))

Output —

[(100, 500), (100, 600), (200, 500), (200, 600)]

vii) compress()

Syntax —

itertools.compress (data, selectors)

Code —

import itertools

import operator



countries = ['USA', 'Australia', 'Canada','Germany']

selectors = [False, False, True, True]



result = itertools.compress(countries, selectors)



for i in result:

print(i)

Output —

Canada

Germany

viii) starmap()

It is used when an iterable is contained within another iterable and to apply any function where each element of iterable to be considered seperate.

Syntax —

itertools.starmap (function, iterable)

Code —

from itertools import starmap



a =[(1,5), (3, 2), (4, 3)]



new_a = list(starmap(pow, a))



print(new_a)

Output —

[1, 9, 64]

ix) chain()

It is used for treating consecutive sequences as a single sequence.

Syntax —

itertools.chain (*iterables)

Code —

from itertools import chain



list_one =['Steve', 'Naina', 'Groot'] result = list(chain(list_one))



result_ci = list(chain.from_iterable(li))



print("Chain Output :", result)



print("chain.from_iterable Output :", result_ci)

Output —

Chain Output : ['Steve', 'Naina', 'Groot']

chain.from_iterable Output : ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L']

x)zip_longest()

It is used to make an iterator that aggregates elements from each of the iterables.

Syntax —

itertools.zip_longest (*iterables, fillvalue=None)

Code —

from itertools import zip_longest



list_one =[100, 200, 300, 400, 500, 600]

list_two =[800, 900, 1000]

z = list(zip_longest(list_one, list_two))

print(z)

Output —