Extras

circuitpython_rawpixel-648581-unsplash.jpg
Photo by rawpixel on Unsplash

The CPython documentation provides a selection of useful functions that are built on top of itertools. These have been made available in the adafruit_itertools_extras module. not only are these useful, but looking through the implementations is instructive on how iterators and the itertools functions can be used.

all_equal(iterable)

Returns True if all the elements of iterable are equal to each other.

>>> all_equal([6, 2*3, 12//2, 4+2])
True
>>> all_equal([6, 2*3, 12//2, 5, 4+2])
False

dotproduct(vec1, vec2)

Compute the dot product of two vectors. This is the sum of the products of pairs (one item from each vector)

>>> dotproduct([1, 2, 3], [1, 2, 3])
14

This is equivalent to (1 * 1) + (2 * 2) + (3 * 3) = 1 + 4 + 9 = 14

first_true(iterable, default=False, pred=None)

Returns the first truthy value in iterable, i.e. the first value x for which bool(x) evaluates to True.

If no true value is found, returns default.

If pred is not None, returns the first item for which pred(item) is true.

first_true([a,b,c], x) is equivalent a or b or c or x
first_true([a,b], x, f) is equivalent a if f(a) else b if f(b) else x

flatten(iterable_of_iterables)

Flatten one level of nesting.

>>> list(flatten(['ABC', 'DEF']))
['A', 'B', 'C', 'D', 'E', 'F']

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

grouper(iterable, n, fillvalue=None)

Collect data from iterable into fixed-length chunks of size n. The final chunk will be filled in with fillvalue if iterable has less that a multiple of n elements.

>>> list(grouper('ABCDEFG', 3, 'x'))
[('A', 'B', 'C'), ('D', 'E', 'F'), ('G', 'x', 'x')]
>>> list(grouper('ABCDEFG', 2))
[('A', 'B'), ('C', 'D'), ('E', 'F'), ('G', None)]

iter_except(func, exception)

Call func repeatedly until exception is raised, yielding the result of each call.

>>> s = [1, 2, 3]
>>> s.pop()
3
>>> s.pop()
2
>>> s.pop()
1
>>> s.pop()
Traceback (most recent call last):
File "", line 1, in
IndexError: pop from empty list

>>> s = [1, 2, 3]
>>> list(iter_except(s.pop, IndexError))
[3, 2, 1]

ncycles(iterable, n)

Returns an iterable from n copies of the elements from iterable.

>>> list(ncycles('ABC', 3))
['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C']

nth(iterable, n, default=None)

Returns the nth (0-based) item of iterable or a default value (None by default) if n is out of range.

>>> nth('ABCD', 0)
'A'
>>> nth('ABCD', 3)
'D'
>>> nth('ABCD', 4)
>>> nth('ABCD', 4, 'Z')
'Z'

padnone(iterable)

Returns the elements from iterable and then returns None indefinitely.

Useful for emulating the behavior of the built-in map() function.

take(5, padnone([1, 2, 3])) -> 1 2 3 None None

pairwise(iterable)

Pair up values in iterable.

>>> list(pairwise(range(5)))
[(0, 1), (1, 2), (2, 3), (3, 4)]

partition(predicate, iterable)

Use predicate to partition entries in iterable into false entries and true entries.

>>> t, f = partition(lambda x: x % 2, range(10))
>>> list(t)
[0, 2, 4, 6, 8]
>>> list(f)
[1, 3, 5, 7, 9]

prepend(value, iterator)

Prepend a value in front of iterator.

prepend(1, [2, 3, 4]) -> 1 2 3 4

quantify(iterable, predicate=bool)

Count the number of elements in iterable for which predicate is True. By default it counts elements x where bool(x) results in True.

>>> quantify([2, 56, 3, 10, 85], lambda x: x >= 10)
3

repeatfunc(func, times=None, *args)

Lazily repeat calls to func a number of times set by times with specified arguments (if any). If times is None (the default), call it infinitely. Return values from the function are generated by the resulting iterator.

>>> take(5, repeatfunc(random.random))
[0.777482, 0.718999, 0.953034, 0.388373, 0.982035]

roundrobin(*iterables)

Return an iterable created by repeatedly picking a value from each of iterables, in order. As individual iterables are exhausted, they are dropped from the picking.

>>> list(roundrobin('ABC', 'D', 'EF'))
['A', 'D', 'E', 'B', 'F', 'C']

tabulate(function, start=0)

Return an iterable populated by applying function to a sequence of consecutive integers, starting at start (defaults to 0).

>>> take(5, tabulate(lambda x: x * x))
[0, 1, 4, 9, 16]

tail(n, iterable)

Return an iterator over the last n items of iterable. This only works if iterable is finite.

>>> list(tail(3, 'ABCDEFG'))
['E', 'F', 'G']

take(n, iterable)

Return first n items of iterable as a list.

>>> take(3, 'ABCDEF')
['A', 'B', 'C']

This guide was first published on Mar 25, 2019. It was last updated on Mar 25, 2019. This page (Extras) was last updated on Aug 12, 2019.