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

## 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.

## 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.

## 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.