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

1. `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 is `itertools.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)]
``````
2. `cycle` creates a copy of an iterable and start iterating over the copied version when the previous iterator is exhausted. Typically, the basic syntax is`itertools.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']
``````
3. `combinations` and `permutations` provides the mathematical combination and permutation over a iterable. Typically, the syntax are `itertools.combinations(iterable, r)` and `itertools.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')]
``````
4. Cartesian Product using `product()`. The syntax is `itertools.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')]
``````
5. `chain()` makes an iterator that returns sequential iterators from the sequential iterables. The syntax is `itertools.chain(*iterables)`.

`````` combined = list(it.chain(letters,numbers))
print(combined)
# ['a', 'b', 'c', 0, 1, 2]
``````
6. `compress()` works like a filter. The syntax is `itertools.compress(data, selectors)`.
`````` mylist = ["a","b","c"]
my_bool = [True,False,True]
filtered = list(it.compress(mylist,my_bool))
print(filtered)
# ['a', 'c']
``````
7. `accumulate()` makes an iterator that returns accumulated result of of any binary functions. The syntax is `itertools.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` functions

`````` acc_sub = list(it.accumulate(numbers,
lambda x, y: y - x))
``````
8. `tee()` returns \$n\$ number of independent copies of a single iterable. The standard syntax is `itertools.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]
``````
9. `islice()` returns selected elements from the iterable. Works similar to the `range()` function. The basic syntax is `itertools.islice(iterable, stop)` or `itertools.`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.

Tags:

Categories:

Updated: