Itertools
The module itertools is a standard library that contains several functions that are useful in functional programming. Advanced iteration functions capabilities for:
Infinite iterators
Iterator | Arguments | Syntax | Example |
---|---|---|---|
count() | start, [step] | start, start+step, start+2*step, … | count(10) --> 10 11 12 13 14 ... |
cycle() | p | p0, p1, … plast, p0, p1, … | cycle('ABCD') --> A B C D A B C D ... |
repeat() | elem [,n] | elem, elem, elem, … endlessly or up to n times | repeat(10, 3) --> 10 10 10 |
- The function count() counts up infinitely from a value.
from itertools import count
for i in count(3):
print(i)
if i>=11:
break
3
4
5
6
7
8
9
10
11
import itertools
# use count to create a simple counter
count1 = itertools.count(100, 10)
print(next(count1))
print(next(count1))
print(next(count1))
100
110
120
- The function cycle() infinitely iterates through an iterable (for instance a list or string).
import itertools
# cycle iterator can be used to cycle over a collection
seq1 = ["Joe", "John", "Mike"]
cycle1 = itertools.cycle(seq1)
print(next(cycle1))
print(next(cycle1))
print(next(cycle1))
print(next(cycle1))
Joe
John
Mike
Joe
- The function repeat() repeats an object, either infinitely or a specific number of times.
A common use for repeat is to supply a stream of constant values to map or zip
list(map(pow, range(10), itertools.repeat(2)))
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Iterators terminating on the shortest input sequence
Iterator | Arguments | Syntax | Example |
---|---|---|---|
accumulate() | p [,func] | p0, p0+p1, p0+p1+p2, … | accumulate([1,2,3,4,5]) --> 1 3 6 10 15 |
dropwhile() | pred, seq | seq[n], seq[n+1], starting when pred fails | dropwhile(lambda x: x<5, [1,4,6,4,1]) --> 6 4 1 |
takewhile() | pred, seq | seq[0], seq[1], until pred fails | takewhile(lambda x: x<5, [1,4,6,4,1]) --> 1 4 |
chain() | p, q, … | p0, p1, … plast, q0, q1, … | chain('ABC', 'DEF') --> A B C D E F |
chain.from_iterable() | iterable | p0, p1, … plast, q0, q1, … | chain.from_iterable(['ABC', 'DEF']) --> A B C D E F |
groupby() | iterable[, key] | sub-iterators grouped by value of key(v) | |
zip_longest() | p, q, … | (p[0], q[0]), (p[1], q[1]), … | zip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D- |
compress() | data, selectors | (d[0] if s[0]), (d[1] if s[1]), … | compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F |
filterfalse() | pred, seq | elements of seq where pred(elem) is false | filterfalse(lambda x: x%2, range(10)) --> 0 2 4 6 8 |
islice() | seq, [start,] stop [, step] | elements from seq[start:stop:step] | islice('ABCDEFG', 2, None) --> C D E F G |
pairwise() | iterable | (p[0], p[1]), (p[1], p[2]) | pairwise('ABCDEFG') --> AB BC CD DE EF FG |
starmap() | func, seq | func(seq[0]), func(seq[1]), … | starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000 |
tee() | it, n | it1, it2, … itn splits one iterator into n |
- accumulate() - returns a running total of values in an iterable
from itertools import accumulate
nums= list(accumulate(range(8)))
print(nums)
[0, 1, 3, 6, 10, 15, 21, 28]
# accumulate creates an iterator that accumulates values
vals = [10,20,30,40,50,40,30]
acc = itertools.accumulate(vals, max)
print(list(acc))
[10, 20, 30, 40, 50, 50, 50]
- takewhile() - takes items from an iterable while a predicate function remains true
from itertools import accumulate, takewhile
nums= list(accumulate(range(8)))
print(nums)
print(list(takewhile(lambda x:x<=6,nums)))
[0, 1, 3, 6, 10, 15, 21, 28]
[0, 1, 3, 6]
- dropwhile() - drops elements from the iterable as long as the predicate is true
# advanced iteration functions in the itertools package
import itertools
def testFunction(x):
return x < 40
def main():
# dropwhile and takewhile will return values until
# a certain condition is met that stops them
print(list(itertools.dropwhile(testFunction, vals)))
print(list(itertools.takewhile(testFunction, vals)))
if __name__ == "__main__":
main()
[40, 50, 40, 30]
[10, 20, 30]
- chain() - combines several iterables into one long one
# advanced iteration functions in the itertools package
import itertools
def main():
# use chain to connect sequences together
x = itertools.chain("ABCD", "1234")
print(list(x))
if __name__ == "__main__":
main()
['A', 'B', 'C', 'D', '1', '2', '3', '4']
Combinatoric iterators
- Product : cartesian product, equivalent to a nested for-loop
print(list(itertools.product('ABC', repeat=2)))
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'B'), ('B', 'C'), ('C', 'A'), ('C', 'B'), ('C', 'C')]
- Permutations: r-length tuples, all possible orderings, no repeated elements
print(list(itertools.permutations('ABC', 2)))
[('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
from itertools import product, permutations
letters=("A","B")
print(list(product(letters,range(2))))
print(list(permutations(letters)))
[('A', 0), ('A', 1), ('B', 0), ('B', 1)]
[('A', 'B'), ('B', 'A')]
- Combinations : r-length tuples, in sorted order, no repeated elements
print(list(itertools.combinations('ABC', 2)))
[('A', 'B'), ('A', 'C'), ('B', 'C')]
- combinations_with_replacement : r-length tuples, in sorted order, with repeated elements
print(list(itertools.combinations_with_replacement('ABC', 2)))
[('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]