From 654241bda10e6450d18bf5846fdf99d8c9c8882b Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 4 Feb 2026 10:39:38 -0600 Subject: [PATCH 1/7] Add running_mean recipe to demonstrate accumulate and count --- Doc/library/itertools.rst | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 08dacb505f7748..90c54979540829 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -845,7 +845,7 @@ and :term:`generators ` which incur interpreter overhead. from contextlib import suppress from functools import reduce from math import comb, isqrt, prod, sumprod - from operator import getitem, is_not, itemgetter, mul, neg + from operator import getitem, is_not, itemgetter, mul, neg, truediv # ==== Basic one liners ==== @@ -862,6 +862,11 @@ and :term:`generators ` which incur interpreter overhead. "Return function(0), function(1), ..." return map(function, count(start)) + def running_mean(iterable): + "Yield the cumulative arithmetic mean." + # running_mean([8.5, 9.5, 7.5, 7.0]) -> 8.5 9.0 8.5 8.0 + return map(truediv, accumulate(iterable), count(1)) + def repeatfunc(function, times=None, *args): "Repeat calls to a function with specified arguments." if times is None: @@ -1234,6 +1239,10 @@ and :term:`generators ` which incur interpreter overhead. [0, 2, 4, 6] + >>> list(running_median([8.5, 9.5, 7.5, 7.0])) + [8.5, 9.0, 8.5, 8.0] + + >>> for _ in loops(5): ... print('hi') ... From a8fc222df6ec0bc98c4995eff332e384a879ce7c Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 4 Feb 2026 10:43:46 -0600 Subject: [PATCH 2/7] Improve section spacing --- Doc/library/itertools.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 90c54979540829..39b04b2d450fdf 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -847,6 +847,7 @@ and :term:`generators ` which incur interpreter overhead. from math import comb, isqrt, prod, sumprod from operator import getitem, is_not, itemgetter, mul, neg, truediv + # ==== Basic one liners ==== def take(n, iterable): @@ -918,6 +919,7 @@ and :term:`generators ` which incur interpreter overhead. # all_equal('4٤௪౪໔', key=int) → True return len(take(2, groupby(iterable, key))) <= 1 + # ==== Data pipelines ==== def unique_justseen(iterable, key=None): @@ -1026,6 +1028,7 @@ and :term:`generators ` which incur interpreter overhead. while True: yield function() + # ==== Mathematical operations ==== def multinomial(*counts): @@ -1045,6 +1048,7 @@ and :term:`generators ` which incur interpreter overhead. # sum_of_squares([10, 20, 30]) → 1400 return sumprod(*tee(iterable)) + # ==== Matrix operations ==== def reshape(matrix, columns): @@ -1063,6 +1067,7 @@ and :term:`generators ` which incur interpreter overhead. n = len(m2[0]) return batched(starmap(sumprod, product(m1, transpose(m2))), n) + # ==== Polynomial arithmetic ==== def convolve(signal, kernel): @@ -1119,6 +1124,7 @@ and :term:`generators ` which incur interpreter overhead. powers = reversed(range(1, n)) return list(map(mul, coefficients, powers)) + # ==== Number theory ==== def sieve(n): From 97e4e8b67be33e5cf1216141dd8e6d5e586b6fc0 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 4 Feb 2026 10:49:39 -0600 Subject: [PATCH 3/7] Retire the tabulate() recipe --- Doc/library/itertools.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 39b04b2d450fdf..1b39b5066822dd 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -859,10 +859,6 @@ and :term:`generators ` which incur interpreter overhead. # prepend(1, [2, 3, 4]) → 1 2 3 4 return chain([value], iterable) - def tabulate(function, start=0): - "Return function(0), function(1), ..." - return map(function, count(start)) - def running_mean(iterable): "Yield the cumulative arithmetic mean." # running_mean([8.5, 9.5, 7.5, 7.0]) -> 8.5 9.0 8.5 8.0 @@ -1241,10 +1237,6 @@ and :term:`generators ` which incur interpreter overhead. [(0, 'a'), (1, 'b'), (2, 'c')] - >>> list(islice(tabulate(lambda x: 2*x), 4)) - [0, 2, 4, 6] - - >>> list(running_median([8.5, 9.5, 7.5, 7.0])) [8.5, 9.0, 8.5, 8.0] @@ -1813,6 +1805,10 @@ and :term:`generators ` which incur interpreter overhead. # Old recipes and their tests which are guaranteed to continue to work. + def tabulate(function, start=0): + "Return function(0), function(1), ..." + return map(function, count(start)) + def old_sumprod_recipe(vec1, vec2): "Compute a sum of products." return sum(starmap(operator.mul, zip(vec1, vec2, strict=True))) @@ -1892,6 +1888,10 @@ and :term:`generators ` which incur interpreter overhead. .. doctest:: :hide: + >>> list(islice(tabulate(lambda x: 2*x), 4)) + [0, 2, 4, 6] + + >>> dotproduct([1,2,3], [4,5,6]) 32 From 35cd40922d11b2012f42b28c28f5314e267ce985 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 4 Feb 2026 12:55:37 -0600 Subject: [PATCH 4/7] Friendlier docstring --- Doc/library/itertools.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 1b39b5066822dd..5f6d71973f27b6 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -860,7 +860,7 @@ and :term:`generators ` which incur interpreter overhead. return chain([value], iterable) def running_mean(iterable): - "Yield the cumulative arithmetic mean." + "Yield the average of all values seen so far." # running_mean([8.5, 9.5, 7.5, 7.0]) -> 8.5 9.0 8.5 8.0 return map(truediv, accumulate(iterable), count(1)) From dd97d5a3970af55ef579994cb2adab317e65bdf1 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 4 Feb 2026 13:25:20 -0600 Subject: [PATCH 5/7] Fix doctest spacing --- Doc/library/itertools.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 5f6d71973f27b6..145d033e9c4516 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -1238,7 +1238,7 @@ and :term:`generators ` which incur interpreter overhead. >>> list(running_median([8.5, 9.5, 7.5, 7.0])) - [8.5, 9.0, 8.5, 8.0] + [8.5, 9.0, 8.5, 8.0] >>> for _ in loops(5): From 08ce2dd4db2354e85b1d6b00330539df428ae004 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 4 Feb 2026 13:38:17 -0600 Subject: [PATCH 6/7] Fix typo --- Doc/library/itertools.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 145d033e9c4516..6aed4b4fbc13a0 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -1237,7 +1237,7 @@ and :term:`generators ` which incur interpreter overhead. [(0, 'a'), (1, 'b'), (2, 'c')] - >>> list(running_median([8.5, 9.5, 7.5, 7.0])) + >>> list(running_mean([8.5, 9.5, 7.5, 7.0])) [8.5, 9.0, 8.5, 8.0] From aad929f94837299e3929dcbbb1bb92634c40fbed Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Wed, 4 Feb 2026 14:04:51 -0600 Subject: [PATCH 7/7] Fix example --- Doc/library/itertools.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index 6aed4b4fbc13a0..4f73a74bdd17e2 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -861,7 +861,7 @@ and :term:`generators ` which incur interpreter overhead. def running_mean(iterable): "Yield the average of all values seen so far." - # running_mean([8.5, 9.5, 7.5, 7.0]) -> 8.5 9.0 8.5 8.0 + # running_mean([8.5, 9.5, 7.5, 6.5]) -> 8.5 9.0 8.5 8.0 return map(truediv, accumulate(iterable), count(1)) def repeatfunc(function, times=None, *args): @@ -1237,7 +1237,7 @@ and :term:`generators ` which incur interpreter overhead. [(0, 'a'), (1, 'b'), (2, 'c')] - >>> list(running_mean([8.5, 9.5, 7.5, 7.0])) + >>> list(running_mean([8.5, 9.5, 7.5, 6.5])) [8.5, 9.0, 8.5, 8.0]