itertools-len

Building blocks for iterators, preserving their len()s.

This module contains length-preserving wrappers for all itertools and the builtin map(). To use it as drop-in replacement, do:

import itertools_len as itertools
from itertools_len import map

Infinites

count() and cycle() yield infinitely many values and are therefore simply re-exported. repeat() is finite if times is passed.

itertools_len.repeat(obj: T, times: int | None = None) None

for the specified number of times. If not specified, returns the object endlessly. Wraps itertools.repeat().

Shortening/filtering

compress(), dropwhile(), filterfalse(), groupby(), and takewhile() all shorten the passed iterable. Therefore no length can be determined and they are simply re-exported.

Mapping

The following functions map an input iterable 1:1 to an output. For inputs with a length, the output length is the same:

itertools_len.accumulate(iterable: Iterable[A], func: Callable[[A, A], T] = add) None

Return series of accumulated sums (or other binary function results). Wraps itertools.accumulate().

itertools_len.starmap(function: Callable[..., T], iterable: Iterable[Any]) None

Return an iterator whose values are returned from the function evaluated with an argument tuple taken from the given sequence. Wraps itertools.starmap().

itertools_len.map(func: Callable[..., T], *iterables: Iterable[Any]) None

Make an iterator that computes the function using arguments from each of the iterables. Stops when the shortest iterable is exhausted. Wraps map().

itertools_len.zip_longest(*iterables: Iterable[Any], fillvalue: Any | None = None) None

Return a zip_longest object whose .__next__() method returns a tuple where the i-th element comes from the i-th iterable argument. The .__next__() method continues until the longest iterable in the argument sequence is exhausted and then it raises StopIteration. When the shorter iterables are exhausted, the fillvalue is substituted in their place. The fillvalue defaults to None or can be specified by a keyword argument. Wraps itertools.zip_longest().

Chaining

The following functions concatenate the input iterables. Its length is therefore the sum of the inputs’ lengths.

itertools_len.chain(*iterables: Iterable[T]) None

Return a chain object whose .__next__() method returns elements from the first iterable until it is exhausted, then elements from the next iterable, until all of the iterables are exhausted. Wraps itertools.chain().

chain.from_iterable(iterables: Iterable[Iterable[T]]) None

Alternative chain() constructor taking a single iterable argument that evaluates lazily. Wraps itertools.chain.from_iterable().

Pairwise

The following function can loop over a sequence in pairs.

This method has been introduced in Python 3.10, so its length-aware equivalent is only available starting from this Python version.

pairwise(iterable: Iterable[T]) None

Return an iterator of overlapping pairs taken from the input iterator. Wraps itertools.pairwise().

Slicing

The following function slices iterables like slice(), but lazily.

itertools_len.islice(iterable: Iterable[T], start: int | None, stop: int | _Missing = missing, step: int | None = None) None

Return an iterator whose next() method returns selected values from an iterable. If start is specified, will skip all preceding elements; otherwise, start defaults to zero. Step defaults to one. If specified as another value, step determines how many values are skipped between successive calls. Works like a slice() on a list but returns an iterator. Wraps itertools.islice().

Splitting

The following function splits an iterable into multiple independent iterators.

itertools_len.tee(iterable: Iterable[T], n: int = 2) None

Returns a tuple of n independent iterators. Wraps itertools.tee().

Permutations and combinations

The following functions return permutations and combinations of input sequences.

itertools_len.product(*iterables: Iterable[A], repeat: int = 1) None

Cartesian product of input iterables. Equivalent to nested for-loops.

For example, product(A, B) returns the same as: ((x,y) for x in A for y in B). The leftmost iterators are in the outermost for-loop, so the output tuples cycle in a manner similar to an odometer (with the rightmost element changing on every iteration).

To compute the product of an iterable with itself, specify the number of repetitions with the optional repeat keyword argument. For example, product(A, repeat=4) means the same as product(A, A, A, A). Wraps itertools.product().

itertools_len.permutations(iterable: Iterable, r: int | None = None) None

Return successive r-length permutations of elements in the iterable. Wraps itertools.permutations().

permutations.__len__() int

Calculate number of r-permutations of n elements [Uspensky37].

itertools_len.combinations(iterable: Iterable, r: int) None

Return successive r-length combinations of elements in the iterable. Wraps itertools.combinations().

combinations.__len__() int

Calculate binomial coefficient (n over r).

itertools_len.combinations_with_replacement(iterable: Iterable, r: int) None

Return successive r-length combinations of elements in the iterable allowing individual elements to have successive repeats. Wraps itertools.combinations_with_replacement().

References

[Uspensky37]

Uspensky et al. (1937), Introduction To Mathematical Probability p. 18, Mcgraw-hill Book Company London.