Python Itertools Tutorial – A Quick and Easy Guide

Python course with 57 real-time projects - Learn Python

In our write-up on Python Iterables, we took a brief introduction on the Python itertools module. This is what will be the point of focus today’s Python Itertools Tutorial.

Here, we will learn how to get infinite iterators & Combinatoric Iterators by Python Itertools.

Along with this, we will learn how Python Iterators terminating the shortest input sequence.

So, let’s start exploring Python Itertools Tutorial.

Python itertools Tutorial

Python Itertools Tutorial – A Quick and Easy Guide

What are Python Itertools?

The Python itertools module has functions for creating iterators for efficient looping.

While some iterators are infinite, some terminate on the shortest input sequence. Yet, some are combinatoric.

Let’s first discuss infinite iterators.

Infinite Iterators in Python

Some functions are capable of generating infinite iterators. In this Python Itertools tutorial, we will study the following functions:

1. count([start=0, step=1])

count() may take two values- start and step. It then returns a sequence of values from start, with intervals the size of step.

>>> from itertools import count
>>> for i in count(10,2):
                print(i)
                if i>25: break

Output

10
12
14
16
18
20
22
24
26

Here’s count() with one argument:

>>> for i in count(2):
               print(i)

Output

2
3
4
5
6
7
Traceback (most recent call last):File “<pyshell#166>”, line 2, in <module>
print(i)
KeyboardInterrupt

It takes a step of 1. If we call it without an argument, it starts with 0:

>>> for i in count():
                print(i)

Output

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Traceback (most recent call last):File “<pyshell#169>”, line 2, in <module>
print(i)
KeyboardInterrupt

2. cycle(iterable)

cycle() makes an iterator from elements from an iterable, and save a copy of each.

Once exhausted, it returns elements from that copy. This repeats indefinitely.

>>> from itertools import cycle
>>> for i in cycle(['red','green','blue']):
                print(i)

Output

red
green
blue
red
green
blue
red
green
blue
red
green
blue
red
green
blue
Traceback (most recent call last):File “<pyshell#174>”, line 2, in <module>
print(i)
<KeyboardInterrupt

cycle() can take any kind of an iterable.

3. repeat(elem [,n])

This will repeat element elem n-times or endlessly into the iterator.

>>> from itertools import repeat
>>> for i in repeat(‘Red’,3):
                print(i)

Output

Red
Red
Red
>>> for  i in repeat('Red'):
                print(i)

Output

Red
Red
Red
Red
Red
Red
Red
Red
Red
Red
Red
Red
Red
Red
Traceback (most recent call last):File “<pyshell#181>”, line 2, in <module>
print(i)
KeyboardInterrupt

Combinatoric Iterators in Python

Combinatorial pertains to the arrangement of, operation on, and selection of discrete mathematical elements. Let’s now talk about combinatoric iterators.

1. product(*iterables, repeat=1)

product() returns the cartesian product of the input iterables. This is equivalent to a nested for-loop.

>>> for i in product([1,2,3],[4,5,6]):
                print(i)

Output

(1, 4)
(1, 5)
(1, 6)
(2, 4)
(2, 5)
(2, 6)
(3, 4)
(3, 5)
(3, 6)

This is equivalent to iterating over this generator object:

>>> for i in ((i,j) for i in [1,2,3] for j in [4,5,6]):
                print(i)

Output

(1, 4)
(1, 5)
(1, 6)
(2, 4)
(2, 5)
(2, 6)
(3, 4)
(3, 5)
(3, 6)

Let’s take a couple more examples.

>>> for i in product('AB','CD','EF'):
                print(i)

Output

(‘A’, ‘C’, ‘E’)
(‘A’, ‘C’, ‘F’)
(‘A’, ‘D’, ‘E’)
(‘A’, ‘D’, ‘F’)
(‘B’, ‘C’, ‘E’)
(‘B’, ‘C’, ‘F’)
(‘B’, ‘D’, ‘E’)
(‘B’, ‘D’, ‘F’)

Because of the repeat argument, the rightmost element advances with every iteration.

>>> for i in product('AB','CD',repeat=2):
                print(i)

Output

(‘A’, ‘C’, ‘A’, ‘C’)
(‘A’, ‘C’, ‘A’, ‘D’)
(‘A’, ‘C’, ‘B’, ‘C’)
(‘A’, ‘C’, ‘B’, ‘D’)
(‘A’, ‘D’, ‘A’, ‘C’)
(‘A’, ‘D’, ‘A’, ‘D’)
(‘A’, ‘D’, ‘B’, ‘C’)
(‘A’, ‘D’, ‘B’, ‘D’)
(‘B’, ‘C’, ‘A’, ‘C’)
(‘B’, ‘C’, ‘A’, ‘D’)
(‘B’, ‘C’, ‘B’, ‘C’)
(‘B’, ‘C’, ‘B’, ‘D’)
(‘B’, ‘D’, ‘A’, ‘C’)
(‘B’, ‘D’, ‘A’, ‘D’)
(‘B’, ‘D’, ‘B’, ‘C’)
(‘B’, ‘D’, ‘B’, ‘D’)

2. permutations(iterable,r=None)

permutations() returns r-length permutations of elements in the iterable.

It generates all possible permutations in lexicographic order, and there is no repetition of elements.

>>> from itertools import permutations
>>> for i in permutations('ABCD'):
                print(i)

Output

(‘A’, ‘B’, ‘C’, ‘D’)
(‘A’, ‘B’, ‘D’, ‘C’)
(‘A’, ‘C’, ‘B’, ‘D’)
(‘A’, ‘C’, ‘D’, ‘B’)
(‘A’, ‘D’, ‘B’, ‘C’)
(‘A’, ‘D’, ‘C’, ‘B’)
(‘B’, ‘A’, ‘C’, ‘D’)
(‘B’, ‘A’, ‘D’, ‘C’)
(‘B’, ‘C’, ‘A’, ‘D’)
(‘B’, ‘C’, ‘D’, ‘A’)
(‘B’, ‘D’, ‘A’, ‘C’)
(‘B’, ‘D’, ‘C’, ‘A’)
(‘C’, ‘A’, ‘B’, ‘D’)
(‘C’, ‘A’, ‘D’, ‘B’)
(‘C’, ‘B’, ‘A’, ‘D’)
(‘C’, ‘B’, ‘D’, ‘A’)
(‘C’, ‘D’, ‘A’, ‘B’)
(‘C’, ‘D’, ‘B’, ‘A’)
(‘D’, ‘A’, ‘B’, ‘C’)
(‘D’, ‘A’, ‘C’, ‘B’)
(‘D’, ‘B’, ‘A’, ‘C’)
(‘D’, ‘B’, ‘C’, ‘A’)
(‘D’, ‘C’, ‘A’, ‘B’)
(‘D’, ‘C’, ‘B’, ‘A’)

Here, we didn’t pass a second argument to it, so it printed tuples of length 4, which is the length of the iterable.

Now, let’s pass a value 3 to this code.

>>> for i in permutations('ABCD',3):
                print(i)

Output

(‘A’, ‘B’, ‘C’)
(‘A’, ‘B’, ‘D’)
(‘A’, ‘C’, ‘B’)
(‘A’, ‘C’, ‘D’)
(‘A’, ‘D’, ‘B’)
(‘A’, ‘D’, ‘C’)
(‘B’, ‘A’, ‘C’)
(‘B’, ‘A’, ‘D’)
(‘B’, ‘C’, ‘A’)
(‘B’, ‘C’, ‘D’)
(‘B’, ‘D’, ‘A’)
(‘B’, ‘D’, ‘C’)
(‘C’, ‘A’, ‘B’)
(‘C’, ‘A’, ‘D’)
(‘C’, ‘B’, ‘A’)
(‘C’, ‘B’, ‘D’)
(‘C’, ‘D’, ‘A’)
(‘C’, ‘D’, ‘B’)
(‘D’, ‘A’, ‘B’)
(‘D’, ‘A’, ‘C’)
(‘D’, ‘B’, ‘A’)
(‘D’, ‘B’, ‘C’)
(‘D’, ‘C’, ‘A’)
(‘D’, ‘C’, ‘B’)

3. combinations(iterable,r)

This returns subsequences of length r from the elements of the iterable.

>>> from itertools import combinations
>>> for i in combinations('ABCD',2):
                print(i)

Output

(‘A’, ‘B’)
(‘A’, ‘C’)
(‘A’, ‘D’)
(‘B’, ‘C’)
(‘B’, ‘D’)
(‘C’, ‘D’)

If you noticed, this only returns the tuples that are lexicographically ascending.

Let’s take another example.

>>> for i in combinations(range(4),3):
                print(i)

Output

(0, 1, 2)
(0, 1, 3)
(0, 2, 3)
(1, 2, 3)

4. combinations_with_replacement(iterable, r)

This returns r-length subsequences of elements of the iterable, where individual elements may repeat.

>>> from itertools import combinations_with_replacement as cwr
>>> for i in cwr('ABCD',2):
                print(i)

Output

(‘A’, ‘A’)
(‘A’, ‘B’)
(‘A’, ‘C’)
(‘A’, ‘D’)
(‘B’, ‘B’)
(‘B’, ‘C’)
(‘B’, ‘D’)
(‘C’, ‘C’)
(‘C’, ‘D’)
(‘D’, ‘D’)

Iterators Terminating on the Shortest Input Sequence

1. accumulate(iterable [,func])

This makes an iterator with accumulated sums (or accumulated results of a binary function specified).

>>> from itertools import accumulate
>>> for i in accumulate([0,1,0,1,1,2,3,5]):
                print(i)

Output

1
1
2
3
5
8
13

This prints the Fibonacci series.

Let’s take another example.

>>> import operator
>>> for i in accumulate([1,2,3,4,5],operator.mul):
                print(i)

Output

1
2
6
24
120
>>> for i in accumulate([2,1,4,3,5],max):
                print(i)

Output

2
2
4
4
5

2. chain(*iterables)

chain() makes an iterator from elements of the first iterable, then from the second, and so on.

It moves to the next iterable as one iterable exhausts.

>>> from itertools import chain
>>> for i in chain('Hello','World','Bye'):
                print(i)

Output

H
e
l
l
o
W
o
r
l
d
B
y
e

3. chain.from_iterable(iterable)

This is an alternative constructor to chain(). It takes chained inputs from a single iterable argument, and evaluates it lazily.

>>> for i in chain.from_iterable(['Hello','World','Bye']):
               print(i)

Output

H
e
l
l
o
W
o
r
l
d
B
y
e

You don’t need to additionally import anything for this.

4. compress(data, selectors)

This makes an iterator that filters elements, from data, for which selector values amount to True.

>>> from itertools import compress
>>> for i in compress('ABCDEF',[1,0,1,True,0,' ']):
              print(i)

Output

A
C
D
F

5. dropwhile(predicate,iterable)

As long as the predicate is True, it drops elements from the iterable. As soon as it is False, it starts returning every element.

>>> from itertools import dropwhile
>>> for i in dropwhile(lambda x:x<7,[1,2,7,9,5,3,2,9]):
                print(i)

Output

7
9
5
3
2
9

6. filterfalse(predicate,iterable)

This makes an iterator that filters those elements out from the iterator, for which the predicate is True.

>>> from itertools import filterfalse
>>> for i in filterfalse(lambda x:x<7,[1,2,7,9,5,3,2,9]):
                print(i)

Output

7
9
9
>>> for i in filterfalse(lambda x:x%2,[1,2,7,9,5,3,2,9]):
                print(i)

Output

2
2

7. groupby(iterable,key=None)

This makes an iterator that takes the iterable, and returns consecutive keys and groups. These are sub-iterators grouped by the key.

>>> from itertools import groupby
>>> for i,j in groupby('AAAAABBCCCCCDDDCCCBBA'):
                print(list(j))

Output

[‘A’, ‘A’, ‘A’, ‘A’, ‘A’]
[‘B’, ‘B’]
[‘C’, ‘C’, ‘C’, ‘C’, ‘C’]
[‘D’, ‘D’, ‘D’]
[‘C’, ‘C’, ‘C’]
[‘B’, ‘B’]
[‘A’]

8. islice(iterable,stop)

islice(iterable,start,stop [,step])

This makes an iterator that returns selected elements from the iterable.

>>> from itertools import islice
>>> for i in islice([1,2,3,4,5],2):
                print(i)

Output

1
2
>>> for i in islice([1,2,3,4,5],2,5):
                print(i)

Output

3
4
5
>>> for i in islice([1,2,3,4,5],0,5,2):
                print(i)

Output

1
3
5

9. starmap(function,iterable)

This makes an iterator that takes arguments from the iterable, and computes a function.

>>> from itertools import starmap
>>> for i in starmap(operator.sub,[(2,1),(7,3),(15,10)]):
                print(i)

Output

1
4
5

10. takewhile(predicate,iterable)

This makes an iterator which returns elements from the iterator as long as the predicate amounts to True. This is in contrast to dropwhile().

>>> from itertools import takewhile
>>> for i in takewhile(lambda x:x<7,[1,2,7,9,5,3,2,9]):
                print(i)

Output

1
2

11. tee(n=2)

This splits an iterator into n independent iterators.

>>> from itertools import tee
>>> for i in tee([1,2,3,4,5,6,7],3):
                for j in i: print(j)
                print()

Output

1
2
3
4
5
6
71
2
3
4
5
6
71
2
3
4
5
6
7

12. zip_longest(*iterables,fillvalue=None)

This makes an iterator by aggregating elements from each iterable. The fillvalue parameter tells it a value to fill for the remaining places in the shorter iterable.

>>> from itertools import zip_longest
>>> for i in zip_longest('ABC','12345',fillvalue='*'):
                print(i)

Output

(‘A’, ‘1’)
(‘B’, ‘2’)
(‘C’, ‘3’)
(‘*’, ‘4’)
(‘*’, ‘5’)
>>> for i in zip_longest('ABC','12345','Hello',fillvalue='*'):
                print(i)

Output

(‘A’, ‘1’, ‘H’)
(‘B’, ‘2’, ‘e’)
(‘C’, ‘3’, ‘l’)
(‘*’, ‘4’, ‘l’)
(‘*’, ‘5’, ‘o’)

So, this was all about the Python Itertools Tutorial. Hope you like our explanation.

Python Interview Questions on Itertools

  1. What are itertools in Python?
  2. What does itertools do in Python?
  3. Is itertool a standard library in Python?
  4. What are the benefits and limitations of using itertools in Python?
  5. How does itertools work in Python?

Conclusion

In this Python Itertools tutorial, we discussed three kinds of iterators generated by functions from the module itertools.

These are- infinite, combinatorics, and those which terminate on the shortest input sequence.

Your 15 seconds will encourage us to work even harder
Please share your happy experience on Google

follow dataflair on YouTube

5 Responses

  1. Bhola Nath Yadav says:

    Whenever we open a topic to study a corresponding tab out of all the topics listed gets highlighted in the left side. But, when I opened this topic, I am not getting to see any corresponding tab getting highlighted. Does that mean there are more topics to study and not included in the top-to-bottom list in the left side? How do we search those topics? This is worrying me. Please help.

    • DataFlair Team says:

      Hey, Bhola Nath

      Your observation is appreciated. Thanks for acknowledging. Our deep apologies for your inconvenience. We have corrected the error. Also, the whole lis of tutorials has been cross checked by our team which are present in sidebar.All topics are included in it, so you can have a great read ahead. We aim at providing best to our readers.

      Thanks for visiting DataFlair

  2. Ken Popkin says:

    Thank you!! Great tutorial!!

    • DataFlair Team says:

      Hello Ken,
      Thanks for the appreciation for Python Itertools. We have 100+ Python tutorials with Latest Interview Question, Please refer them too,
      Regards,
      DataFlair

  3. Sneha says:

    great knowledge imparted to me about itertools as opposed to what everyon used to say its confusing..
    Keep up the good work!
    Regards,
    Sneha Nair

Leave a Reply

Your email address will not be published. Required fields are marked *