Useful Functions of Python Itertools Module
Python itertools
module provide memory-efficient solutions for producing complex iterators. It is quite useful in different situations where it provides functionalities for faster programs along with efficient memory usage.
In this post, we will take a look at some basic functions of this module.
zip_longest()
fills-up zip list for uneven lengths of lists. It fills the empty spaces in pairs with a given value. Typically, the basic syntax isitertools.zip_longest(*iterables, fillvalue=None)
.mylist = ["a","b","c"] index_items = list(zip(range(1,10),mylist)) print(index_items) index_future_items = list(it.zip_longest(range(1,10),mylist)) print(index_future_items) # [(1, 'a'), (2, 'b'), (3, 'c')] # [(1, 'a'), (2, 'b'), (3, 'c'), (4, None), (5, None), (6, None), (7, None), (8, None), (9, None)]
cycle
creates a copy of an iterable and start iterating over the copied version when the previous iterator is exhausted. Typically, the basic syntax isitertools.cycle(iterable)
. This function is useful for writing the simplest round-robin function in just two lines.mylist = ["a","b","c"] my_list_cycle = it.cycle(mylist) new_list = [next(my_list_cycle) for _ in range(5)] print(new_list) # ['a', 'b', 'c', 'a', 'b']
combinations
andpermutations
provides the mathematical combination and permutation over a iterable. Typically, the syntax areitertools.combinations(iterable, r)
anditertools.permutations(iterable, r)
.mylist = ["a","b","c"] combination = list(it.combinations(mylist,2)) permutation = list(it.permutations(mylist,2)) print(combination) print(permutation) # [('a', 'b'), ('a', 'c'), ('b', 'c')] # [('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'c'), ('c', 'a'), ('c', 'b')]
- Cartesian Product using
product()
. The syntax isitertools.product(*iterables, repeat=1)
.letters = ["a","b","c"] numbers = [0,1,2] cart_product_1 = list(it.product(numbers,letters)) cart_product_2 = list(it.product(numbers,letters, repeat=2)) print(cart_product_1) print(cart_product_2) # [(0, 'a'), (0, 'b'), (0, 'c'), (1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c')] # [(0, 'a', 0, 'a'), (0, 'a', 0, 'b'), (0, 'a', 0, 'c'), (0, 'a', 1, 'a'), (0, 'a', 1, 'b'), (0, 'a', 1, 'c'), (0, 'a', 2, 'a'), (0, 'a', 2, 'b'), (0, 'a', 2, 'c'), (0, 'b', 0, 'a'), (0, 'b', 0, 'b'), (0, 'b', 0, 'c'), (0, 'b', 1, 'a'), (0, 'b', 1, 'b'), (0, 'b', 1, 'c'), (0, 'b', 2, 'a'), (0, 'b', 2, 'b'), (0, 'b', 2, 'c'), (0, 'c', 0, 'a'), (0, 'c', 0, 'b'), (0, 'c', 0, 'c'), (0, 'c', 1, 'a'), (0, 'c', 1, 'b'), (0, 'c', 1, 'c'), (0, 'c', 2, 'a'), (0, 'c', 2, 'b'), (0, 'c', 2, 'c'), (1, 'a', 0, 'a'), (1, 'a', 0, 'b'), (1, 'a', 0, 'c'), (1, 'a', 1, 'a'), (1, 'a', 1, 'b'), (1, 'a', 1, 'c'), (1, 'a', 2, 'a'), (1, 'a', 2, 'b'), (1, 'a', 2, 'c'), (1, 'b', 0, 'a'), (1, 'b', 0, 'b'), (1, 'b', 0, 'c'), (1, 'b', 1, 'a'), (1, 'b', 1, 'b'), (1, 'b', 1, 'c'), (1, 'b', 2, 'a'), (1, 'b', 2, 'b'), (1, 'b', 2, 'c'), (1, 'c', 0, 'a'), (1, 'c', 0, 'b'), (1, 'c', 0, 'c'), (1, 'c', 1, 'a'), (1, 'c', 1, 'b'), (1, 'c', 1, 'c'), (1, 'c', 2, 'a'), (1, 'c', 2, 'b'), (1, 'c', 2, 'c'), (2, 'a', 0, 'a'), (2, 'a', 0, 'b'), (2, 'a', 0, 'c'), (2, 'a', 1, 'a'), (2, 'a', 1, 'b'), (2, 'a', 1, 'c'), (2, 'a', 2, 'a'), (2, 'a', 2, 'b'), (2, 'a', 2, 'c'), (2, 'b', 0, 'a'), (2, 'b', 0, 'b'), (2, 'b', 0, 'c'), (2, 'b', 1, 'a'), (2, 'b', 1, 'b'), (2, 'b', 1, 'c'), (2, 'b', 2, 'a'), (2, 'b', 2, 'b'), (2, 'b', 2, 'c'), (2, 'c', 0, 'a'), (2, 'c', 0, 'b'), (2, 'c', 0, 'c'), (2, 'c', 1, 'a'), (2, 'c', 1, 'b'), (2, 'c', 1, 'c'), (2, 'c', 2, 'a'), (2, 'c', 2, 'b'), (2, 'c', 2, 'c')]
-
chain()
makes an iterator that returns sequential iterators from the sequential iterables. The syntax isitertools.chain(*iterables)
.combined = list(it.chain(letters,numbers)) print(combined) # ['a', 'b', 'c', 0, 1, 2]
compress()
works like a filter. The syntax isitertools.compress(data, selectors)
.mylist = ["a","b","c"] my_bool = [True,False,True] filtered = list(it.compress(mylist,my_bool)) print(filtered) # ['a', 'c']
-
accumulate()
makes an iterator that returns accumulated result of of any binary functions. The syntax isitertools.accumulate(iterable[, func, *, initial=None])
.import operator as op acc = list(it.accumulate(numbers)) acc_mul = list(it.accumulate(numbers, op.mul)) acc_sub = list(it.accumulate(numbers, op.sub)) acc_div = list(it.accumulate(numbers, op.floordiv)) print(acc) print(acc_sub) print(acc_mul) print(acc_div) # [1, 3, 6, 10] # [1, -1, -4, -8] # [1, 2, 6, 24] # [1, 0, 0, 0]
or you can use customized
lambda
functionsacc_sub = list(it.accumulate(numbers, lambda x, y: y - x))
-
tee()
returns $n$ number of independent copies of a single iterable. The standard syntax isitertools.tee(iterable, n=2)
.numbers = [1,2,3,4] c1, c2, c3 = it.tee(numbers,3) print(list(c1), list(c2), list(c3)) # [1, 2, 3, 4] [1, 2, 3, 4] [1, 2, 3, 4]
-
islice()
returns selected elements from the iterable. Works similar to therange()
function. The basic syntax isitertools.islice(iterable, stop)
oritertools.
islice(iterable, start, stop[, step])
.my_slice = list(it.islice([1, 2, 3, 4], 1, 3)) print(my_slice) evenlist = list(it.islice(list(range(20)),2,15,2)) print(evenlist) # [2, 3] # [2, 4, 6, 8, 10, 12, 14]
There are some other useful functions too. I included only the most common ones here. For more details, checkout the Official Documentation.
Leave a comment