Skip to content

itertools Recipes

Common utility functions built from itertools primitives, providing elegant solutions to frequent programming tasks.

Mental Model

itertools recipes are pre-assembled pipelines built from the module's primitives — the same way you combine basic LEGO bricks into recognizable structures. Functions like flatten, pairwise, and batched appear so often that they have become community standards. Knowing these recipes saves you from reinventing common patterns and signals clear intent to other developers.

flatten() - Flatten Nested Iterables

Flatten a list of lists into a single sequence.

```python from itertools import chain

def flatten(list_of_lists): return chain.from_iterable(list_of_lists)

data = [[1, 2], [3, 4], [5, 6]] result = list(flatten(data)) print(result) ```

[1, 2, 3, 4, 5, 6]

roundrobin() - Interleave Iterables

Take elements from each iterable in turn.

```python from itertools import cycle, chain

def roundrobin(*iterables): pending = len(iterables) nexts = cycle(iter(it).next for it in iterables) while pending: try: for next in nexts: yield next() except StopIteration: pending -= 1 nexts = cycle(iter(it).next for it in iterables)

result = list(roundrobin('ABC', 'D', 'EF')) print(result) ```

['A', 'D', 'E', 'B', 'F', 'C']

partition() - Separate Elements by Predicate

Partition an iterable into two based on a condition.

```python from itertools import tee

def partition(pred, iterable): t1, t2 = tee(iterable) return (filter(pred, t1), filterfalse(pred, t2))

from itertools import filterfalse numbers = [1, 2, 3, 4, 5, 6, 7, 8] evens, odds = partition(lambda x: x % 2 == 0, numbers) print("Evens:", list(evens)) print("Odds:", list(odds)) ```

Evens: [2, 4, 6, 8] Odds: [1, 3, 5, 7]


Exercises

Exercise 1. Implement a roundrobin function that takes multiple iterables and yields items from each in turn, cycling through them until all are exhausted. For example, list(roundrobin("ABC", "D", "EF")) should return ['A', 'D', 'E', 'B', 'F', 'C'].

Solution to Exercise 1

```python from itertools import cycle, islice

def roundrobin(*iterables): pending = len(iterables) nexts = cycle(iter(it).next for it in iterables) while pending: try: for next_fn in nexts: yield next_fn() except StopIteration: pending -= 1 nexts = cycle(islice(nexts, pending))

Test

print(list(roundrobin("ABC", "D", "EF")))

['A', 'D', 'E', 'B', 'F', 'C']

```


Exercise 2. Implement a flatten function that recursively flattens nested lists of arbitrary depth using itertools. For example, flatten([1, [2, [3, 4], 5], [6]]) should return [1, 2, 3, 4, 5, 6].

Solution to Exercise 2

```python from itertools import chain

def flatten(nested): result = [] for item in nested: if isinstance(item, list): result.extend(flatten(item)) else: result.append(item) return result

Test

print(flatten([1, [2, [3, 4], 5], [6]]))

[1, 2, 3, 4, 5, 6]

```


Exercise 3. Implement a unique_everseen function that yields unique elements from an iterable, preserving order and remembering all previously seen elements. For example, list(unique_everseen("AABBCCDDA")) should return ['A', 'B', 'C', 'D'].

Solution to Exercise 3

```python def unique_everseen(iterable): seen = set() for item in iterable: if item not in seen: seen.add(item) yield item

Test

print(list(unique_everseen("AABBCCDDA")))

['A', 'B', 'C', 'D']

print(list(unique_everseen([3, 1, 4, 1, 5, 9, 2, 6, 5])))

[3, 1, 4, 5, 9, 2, 6]

```