Updated On : Nov-17,2019 Time Investment : ~25 mins

Overview

It provides a list of iterator for some common tasks like permutations, combinations, infinite iterators, cycle looping, etc.

import itertools
from datetime import datetime
import time

Infinite Iterators:

  • count(start=0,step=1) - Keeps on increasing count by step from start until loop is stopped by some condition.
  • cycle(iterable) - keeps on looping through iterable infinite times. After the last element has used it again starts from the first one like a cycle.
  • repeat(object[,times=None]) - Keeps on repeating object infinite times until stopped by some loop. If times are provided as some integer then it repeats that many times.
result = []
for i in itertools.count(5, 5):
    if i <= 100:
        result.append(i)
    else:
        break
print(result)

result = []
for i in itertools.cycle(range(1,6)):
    if len(result) < 15:
        result.append(i)
    else:
        break
print(result)

result = []
for i in itertools.cycle(['B','O','B']):
    if len(result) < 15:
        result.append(i)
    else:
        break
print(result)

print(list(itertools.repeat('A', 5)))
print(list(itertools.repeat([1,2], 5)))
print(list(itertools.repeat({'key':'val'}, 7)))
[5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100]
[1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
['B', 'O', 'B', 'B', 'O', 'B', 'B', 'O', 'B', 'B', 'O', 'B', 'B', 'O', 'B']
['A', 'A', 'A', 'A', 'A']
[[1, 2], [1, 2], [1, 2], [1, 2], [1, 2]]
[{'key': 'val'}, {'key': 'val'}, {'key': 'val'}, {'key': 'val'}, {'key': 'val'}, {'key': 'val'}, {'key': 'val'}]

Other short sequence terminators:

  • accumulate(iterable[,func]) - It returns accumulated sum of numbers if func is not provided else applies binary func to elements of iterable.
  • chain(*iterables) - It loops through all iterables passed as arguments and returns elements of each one by one in sequence they were given input.
  • compress(data,selectors) - It loop through data one by one and returns only that elements for which element with same index in selectors return True.
print(list(itertools.accumulate(range(5,15))))
print(list(itertools.accumulate(range(5,15), lambda x,y : x*y)))
print(list(itertools.accumulate(range(5,15), lambda x,y : y/x)))
print(list(itertools.accumulate('ABCD')))
print(list(itertools.accumulate('ABCD', lambda x,y : [x,y])))

print(list(itertools.chain(range(1,4),range(4, 1,-1),'ABCDE')))

print(list(itertools.compress(range(5,0,-1),[True,False,True,False,True])))
print(list(itertools.compress(range(5,0,-1),[True,None,None,False,True])))
print(list(itertools.compress(range(5,0,-1),[0,1,1,1,0])))
print(list(itertools.compress(range(5,0,-1),[[],[1,2],[],[1,2,3],[]])))
print(list(itertools.compress(range(5,0,-1),[{},{'key':'val'},{'key':'val'},{},{}])))
[5, 11, 18, 26, 35, 45, 56, 68, 81, 95]
[5, 30, 210, 1680, 15120, 151200, 1663200, 19958400, 259459200, 3632428800]
[5, 1.2, 5.833333333333334, 1.3714285714285712, 6.562500000000001, 1.5238095238095235, 7.218750000000002, 1.662337662337662, 7.820312500000002, 1.7902097902097898]
['A', 'AB', 'ABC', 'ABCD']
['A', ['A', 'B'], [['A', 'B'], 'C'], [[['A', 'B'], 'C'], 'D']]
[1, 2, 3, 4, 3, 2, 'A', 'B', 'C', 'D', 'E']
[5, 3, 1]
[5, 1]
[4, 3, 2]
[4, 2]
[4, 3]
  • dropwhile(predicate,iterable) - It drops element as long as predicate condition is True and then it returns all elements.
  • filterfalse(predicate,iterable) - It returns only those elements from iterable for which predicate condition is False.
print(list(itertools.dropwhile(lambda x: x<2, range(1,6))))
print(list(itertools.dropwhile(lambda x: x == 2, range(1,6)))) ## Make a note here that first condition itself is False hence returns all elements
print(list(itertools.dropwhile(lambda x: (x**2) < 5, range(1,6))))
print(list(itertools.dropwhile(lambda x : x in ['A','E','I','O','U'], 'EABCD')))

print(list(itertools.filterfalse(lambda x: x%2==0, range(1,6))))
print(list(itertools.filterfalse(lambda x: x//2 < 2, range(1,6))))
print(list(itertools.filterfalse(None, range(6))))
print(list(itertools.filterfalse(lambda x : x in ['A','E','I','O','U'], 'ABCDE')))
[2, 3, 4, 5]
[1, 2, 3, 4, 5]
[3, 4, 5]
['B', 'C', 'D']
[1, 3, 5]
[4, 5]
[0]
['B', 'C', 'D']
  • groupby(iterable,key=None) - Returns an iterator which consists of key, group pair from iterable based on function provided as key which generates key in pair. If key is not provided then it's set to identity function(lambda x: x). iterable should be sorted to get proper results/grouping. Elements should be in sorted order to get proper groups.
for key,group in itertools.groupby([2,2,2,3,3,4,4]):
    print(str(key)+ ' : ' + str(list(group)))
for key,group in itertools.groupby(['Arial','Ariel','Bad','Bed','Cat','Catch'],key=lambda x: x[0]):
    print(str(key)+ ' : ' + str(list(group)))

class Employee(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __str__(self):
        return self.name + ' : , Age : '+str(self.age)

e1 = Employee('Sunny',27)
e2 = Employee('Sumit',27)
e3 = Employee('Anup',35)
e4 = Employee('Ashwin',35)
e5 = Employee('Rohit',38)
e6 = Employee('Irfan',38)
e7 = Employee('Ethesh',22)
e8 = Employee('Kaushal',45)

for key,group in itertools.groupby([e1,e2,e3,e4,e5,e6,e7,e8], key=lambda x: x.age):
    group_desc = [str(item) for item in group]
    print(str(key)+ ' : ' + str(group_desc))

for key,group in itertools.groupby([e1,e2,e3,e4,e5,e6,e7,e8], key=lambda x: x.name[0]):
    group_desc = [str(item) for item in group]
    print(str(key)+ ' : ' + str(group_desc))
2 : [2, 2, 2]
3 : [3, 3]
4 : [4, 4]
A : ['Arial', 'Ariel']
B : ['Bad', 'Bed']
C : ['Cat', 'Catch']
27 : ['Sunny : , Age : 27', 'Sumit : , Age : 27']
35 : ['Anup : , Age : 35', 'Ashwin : , Age : 35']
38 : ['Rohit : , Age : 38', 'Irfan : , Age : 38']
22 : ['Ethesh : , Age : 22']
45 : ['Kaushal : , Age : 45']
S : ['Sunny : , Age : 27', 'Sumit : , Age : 27']
A : ['Anup : , Age : 35', 'Ashwin : , Age : 35']
R : ['Rohit : , Age : 38']
I : ['Irfan : , Age : 38']
E : ['Ethesh : , Age : 22']
K : ['Kaushal : , Age : 45']
  • islice(iterable, stop) - Loops through iterable and returns element from begining till stop index.
  • islice(iterable, start,stop[,step]) - Loops through iterable from start index till stop index using step for item skipping
  • starmap(function,iterable) - executes function using each argouments of iterable as argument to function.
  • takewhile() - It's reverse of dropwhile() function. It returns element until condition is True whereas dropwhile() drops element while condition is True and then returns elements.
print(list(itertools.islice('ABCDE',3)))
print(list(itertools.islice('ABCDE',0,2)))
print(list(itertools.islice('ABCDE',0,None, 3)))

print(list(itertools.starmap(lambda x: x%2, [(2,),(3,),(4,),(5,),(6,),(7,),(8,)])))
print(list(itertools.starmap(lambda x: datetime.fromtimestamp(x), [(6,),(60,),(3600,)])))
print(list(itertools.starmap(lambda x: time.gmtime(x),[(6,),(60,),(3600,)])))

print(list(itertools.takewhile(lambda x: x<2, range(1,6))))
print(list(itertools.takewhile(lambda x: x == 2, range(1,6)))) ## Make a note here that first condition itself is False hence returns no elements
print(list(itertools.takewhile(lambda x: (x**2) < 5, range(1,6))))
print(list(itertools.takewhile(lambda x : x in ['A','E','I','O','U'], 'EABCD')))
['A', 'B', 'C']
['A', 'B']
['A', 'D']
[0, 1, 0, 1, 0, 1, 0]
[datetime.datetime(1970, 1, 1, 0, 0, 6), datetime.datetime(1970, 1, 1, 0, 1), datetime.datetime(1970, 1, 1, 1, 0)]
[time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=6, tm_wday=3, tm_yday=1, tm_isdst=0), time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=1, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0), time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=1, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)]
[1]
[]
[1, 2]
['E', 'A']
  • tee(iterable,n=2) - It returns n independent iterables from single iterable.
  • zip_longest(*iterable, fill_value=None) - It's same as zip() function but returns elements same as longest sequence and fills value specified by fill_value in other small lists.
result = itertools.tee([1,2,3,4], 4)
print([list(item) for item in result ])

result = itertools.tee('ABCDE', 3)
print([list(item) for item in result ])

print(list(itertools.zip_longest([1,2,3,4,5,6],[1,2,4],[1,2,3,4,5])))
print(list(itertools.zip_longest([1,2,3,4,5,6],[1,2,4],[1,2,3,4,5],'NONE')))
print(list(itertools.zip_longest([1,2,3,4,5,6],[1,2,4],[1,2,3,4,5],'NA')))
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]
[['A', 'B', 'C', 'D', 'E'], ['A', 'B', 'C', 'D', 'E'], ['A', 'B', 'C', 'D', 'E']]
[(1, 1, 1), (2, 2, 2), (3, 4, 3), (4, None, 4), (5, None, 5), (6, None, None)]
[(1, 1, 1, 'N'), (2, 2, 2, 'O'), (3, 4, 3, 'N'), (4, None, 4, 'E'), (5, None, 5, None), (6, None, None, None)]
[(1, 1, 1, 'N'), (2, 2, 2, 'A'), (3, 4, 3, None), (4, None, 4, None), (5, None, 5, None), (6, None, None, None)]

Conbinatorics iterators:

  • product(*iterables) - Returns cartesian product of input iterables. To compute product of iterable with itself specify repeat with number of times you want to repeat.
  • permutations(iterable,r=None) - It returns all possible permutations of lenght r of iterable. If r is not specified then all possible permutation of whole iterable is returned.
  • combinations(iterable,r) - Returns all combinations of length r of iterable.
  • combinations_with_replacement(iterable,r) - Returns all combinations of length r of iterable with allowing replacement more than once.
print(list(itertools.product([1,2,3,4],[4,3,2,1])))
print(list(itertools.product([1,2,3,4],[4,3,2,1],[7,8,9])))
print(list(itertools.product([1,2,3,4],[4,3,])))
print(list(itertools.product([1,2,3,4],[4,3,],repeat=2)))
print(list(itertools.product('CBA','ABC')))
print(list(itertools.product([1,2,3,4],repeat=3)))
[(1, 4), (1, 3), (1, 2), (1, 1), (2, 4), (2, 3), (2, 2), (2, 1), (3, 4), (3, 3), (3, 2), (3, 1), (4, 4), (4, 3), (4, 2), (4, 1)]
[(1, 4, 7), (1, 4, 8), (1, 4, 9), (1, 3, 7), (1, 3, 8), (1, 3, 9), (1, 2, 7), (1, 2, 8), (1, 2, 9), (1, 1, 7), (1, 1, 8), (1, 1, 9), (2, 4, 7), (2, 4, 8), (2, 4, 9), (2, 3, 7), (2, 3, 8), (2, 3, 9), (2, 2, 7), (2, 2, 8), (2, 2, 9), (2, 1, 7), (2, 1, 8), (2, 1, 9), (3, 4, 7), (3, 4, 8), (3, 4, 9), (3, 3, 7), (3, 3, 8), (3, 3, 9), (3, 2, 7), (3, 2, 8), (3, 2, 9), (3, 1, 7), (3, 1, 8), (3, 1, 9), (4, 4, 7), (4, 4, 8), (4, 4, 9), (4, 3, 7), (4, 3, 8), (4, 3, 9), (4, 2, 7), (4, 2, 8), (4, 2, 9), (4, 1, 7), (4, 1, 8), (4, 1, 9)]
[(1, 4), (1, 3), (2, 4), (2, 3), (3, 4), (3, 3), (4, 4), (4, 3)]
[(1, 4, 1, 4), (1, 4, 1, 3), (1, 4, 2, 4), (1, 4, 2, 3), (1, 4, 3, 4), (1, 4, 3, 3), (1, 4, 4, 4), (1, 4, 4, 3), (1, 3, 1, 4), (1, 3, 1, 3), (1, 3, 2, 4), (1, 3, 2, 3), (1, 3, 3, 4), (1, 3, 3, 3), (1, 3, 4, 4), (1, 3, 4, 3), (2, 4, 1, 4), (2, 4, 1, 3), (2, 4, 2, 4), (2, 4, 2, 3), (2, 4, 3, 4), (2, 4, 3, 3), (2, 4, 4, 4), (2, 4, 4, 3), (2, 3, 1, 4), (2, 3, 1, 3), (2, 3, 2, 4), (2, 3, 2, 3), (2, 3, 3, 4), (2, 3, 3, 3), (2, 3, 4, 4), (2, 3, 4, 3), (3, 4, 1, 4), (3, 4, 1, 3), (3, 4, 2, 4), (3, 4, 2, 3), (3, 4, 3, 4), (3, 4, 3, 3), (3, 4, 4, 4), (3, 4, 4, 3), (3, 3, 1, 4), (3, 3, 1, 3), (3, 3, 2, 4), (3, 3, 2, 3), (3, 3, 3, 4), (3, 3, 3, 3), (3, 3, 4, 4), (3, 3, 4, 3), (4, 4, 1, 4), (4, 4, 1, 3), (4, 4, 2, 4), (4, 4, 2, 3), (4, 4, 3, 4), (4, 4, 3, 3), (4, 4, 4, 4), (4, 4, 4, 3), (4, 3, 1, 4), (4, 3, 1, 3), (4, 3, 2, 4), (4, 3, 2, 3), (4, 3, 3, 4), (4, 3, 3, 3), (4, 3, 4, 4), (4, 3, 4, 3)]
[('C', 'A'), ('C', 'B'), ('C', 'C'), ('B', 'A'), ('B', 'B'), ('B', 'C'), ('A', 'A'), ('A', 'B'), ('A', 'C')]
[(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4), (1, 2, 1), (1, 2, 2), (1, 2, 3), (1, 2, 4), (1, 3, 1), (1, 3, 2), (1, 3, 3), (1, 3, 4), (1, 4, 1), (1, 4, 2), (1, 4, 3), (1, 4, 4), (2, 1, 1), (2, 1, 2), (2, 1, 3), (2, 1, 4), (2, 2, 1), (2, 2, 2), (2, 2, 3), (2, 2, 4), (2, 3, 1), (2, 3, 2), (2, 3, 3), (2, 3, 4), (2, 4, 1), (2, 4, 2), (2, 4, 3), (2, 4, 4), (3, 1, 1), (3, 1, 2), (3, 1, 3), (3, 1, 4), (3, 2, 1), (3, 2, 2), (3, 2, 3), (3, 2, 4), (3, 3, 1), (3, 3, 2), (3, 3, 3), (3, 3, 4), (3, 4, 1), (3, 4, 2), (3, 4, 3), (3, 4, 4), (4, 1, 1), (4, 1, 2), (4, 1, 3), (4, 1, 4), (4, 2, 1), (4, 2, 2), (4, 2, 3), (4, 2, 4), (4, 3, 1), (4, 3, 2), (4, 3, 3), (4, 3, 4), (4, 4, 1), (4, 4, 2), (4, 4, 3), (4, 4, 4)]
print(list(itertools.permutations('ABCDE', r=2))) ## Order of elements does matter in permutations
print(list(itertools.permutations('ABC')))
[('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('B', 'A'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'A'), ('C', 'B'), ('C', 'D'), ('C', 'E'), ('D', 'A'), ('D', 'B'), ('D', 'C'), ('D', 'E'), ('E', 'A'), ('E', 'B'), ('E', 'C'), ('E', 'D')]
[('A', 'B', 'C'), ('A', 'C', 'B'), ('B', 'A', 'C'), ('B', 'C', 'A'), ('C', 'A', 'B'), ('C', 'B', 'A')]
print(list(itertools.combinations('ABCDE', r=2))) ## Order of elements does not matter in combintations
print(list(itertools.combinations_with_replacement('ABCDE', r=2))) ## Make a note that element was replaced hence there are extra entry of element with itself.
print(list(itertools.combinations('ABC', r=3)))
[('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'D'), ('C', 'E'), ('D', 'E')]
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('A', 'D'), ('A', 'E'), ('B', 'B'), ('B', 'C'), ('B', 'D'), ('B', 'E'), ('C', 'C'), ('C', 'D'), ('C', 'E'), ('D', 'D'), ('D', 'E'), ('E', 'E')]
[('A', 'B', 'C')]
Sunny Solanki  Sunny Solanki

YouTube Subscribe Comfortable Learning through Video Tutorials?

If you are more comfortable learning through video tutorials then we would recommend that you subscribe to our YouTube channel.

Need Help Stuck Somewhere? Need Help with Coding? Have Doubts About the Topic/Code?

When going through coding examples, it's quite common to have doubts and errors.

If you have doubts about some code examples or are stuck somewhere when trying our code, send us an email at coderzcolumn07@gmail.com. We'll help you or point you in the direction where you can find a solution to your problem.

You can even send us a mail if you are trying something new and need guidance regarding coding. We'll try to respond as soon as possible.

Share Views Want to Share Your Views? Have Any Suggestions?

If you want to

  • provide some suggestions on topic
  • share your views
  • include some details in tutorial
  • suggest some new topics on which we should create tutorials/blogs
Please feel free to contact us at coderzcolumn07@gmail.com. We appreciate and value your feedbacks. You can also support us with a small contribution by clicking DONATE.


Subscribe to Our YouTube Channel

YouTube SubScribe

Newsletter Subscription