Skip to main content

Lib/itertools.py

Source:

cpython 3.14 @ ab2d84fe1023/Modules/itertoolsmodule.c

The itertools module is implemented entirely in C (Modules/itertoolsmodule.c). This page annotates the C source. It provides lazy iterator combinators: chain, cycle, repeat, islice, filterfalse, takewhile, dropwhile, zip_longest, product, permutations, combinations, and combinations_with_replacement.

Map

LinesSymbolRole
1-200chainobject, chain.from_iterableIterator of iterators; lazy flattening
201-400cycleobjectCycling iterator; buffer accumulates then replays
401-600repeatobjectRepeat a value N times or infinitely
601-900isliceobject, takewhile, dropwhileSlicing and predicate-based selection
901-1200filterfalseobject, starmap, ziplongInverse filter; apply; zip with fill
1201-2000productobjectCartesian product; pool arrays and index counter
2001-3000permutationsobjectKnuth Algorithm L in-place permutation
3001-4000combinationsobject, combinations_wrk-subset enumeration

Reading

chain: iterator of iterators

chain holds a source iterator and a current active iterator. chain_next calls next(active); on exhaustion it calls next(source) to get the next iterator and sets it as active.

// Modules/itertoolsmodule.c:1 chainobject
typedef struct {
PyObject_HEAD
PyObject *source; /* outer iterator */
PyObject *active; /* current inner iterator */
} chainobject;

// chain_next
static PyObject *
chain_next(chainobject *lz)
{
PyObject *item;
while (lz->active) {
item = (*Py_TYPE(lz->active)->tp_iternext)(lz->active);
if (item) return item;
Py_CLEAR(lz->active);
lz->active = (*Py_TYPE(lz->source)->tp_iternext)(lz->source);
}
return NULL;
}

product: Cartesian product

product stores the input pools as a list of tuples and an index array. Each call to product_next increments the rightmost index that has not yet exhausted its pool, carrying over to the left when needed (like counting in mixed radix).

// Modules/itertoolsmodule.c:1201 product_next (carry loop)
static PyObject *
product_next(productobject *lz)
{
/* build result tuple from indices */
/* increment: scan right-to-left, carry if pool exhausted */
for (i = npools - 1; i >= 0; i--) {
lz->indices[i]++;
if (lz->indices[i] < PyTuple_GET_SIZE(pool)) break;
lz->indices[i] = 0;
if (i == 0) { lz->stopped = 1; return NULL; }
}
...
}

permutations: Knuth Algorithm L

permutations maintains an array of indices and a cycles array. Each permutations_next call uses Knuth's Algorithm L to advance the permutation in-place without allocating intermediate arrays.

gopy notes

Not yet ported. The planned package path is module/itertools/. Each iterator would be a Go struct implementing a Next() (py.Object, bool) method. Go's iter package (1.23+) provides iter.Seq[V] which maps to the same concept.