Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 66 additions & 9 deletions Doc/library/itertools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,7 @@ and :term:`generators <generator>` which incur interpreter overhead.
from collections import Counter, deque
from contextlib import suppress
from functools import reduce
from heapq import heappush, heappushpop, heappush_max, heappushpop_max
from math import comb, isqrt, prod, sumprod
from operator import getitem, is_not, itemgetter, mul, neg, truediv

Expand All @@ -848,11 +849,6 @@ and :term:`generators <generator>` which incur interpreter overhead.
# prepend(1, [2, 3, 4]) → 1 2 3 4
return chain([value], iterable)

def running_mean(iterable):
"Yield the average of all values seen so far."
# 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):
"Repeat calls to a function with specified arguments."
if times is None:
Expand Down Expand Up @@ -1150,6 +1146,49 @@ and :term:`generators <generator>` which incur interpreter overhead.
return n


# ==== Running statistics ====

def running_mean(iterable):
"Average of values seen so far."
# running_mean([37, 33, 38, 28]) → 37 35 36 34
return map(truediv, accumulate(iterable), count(1))

def running_min(iterable):
"Smallest of values seen so far."
# running_min([37, 33, 38, 28]) → 37 33 33 28
return accumulate(iterable, func=min)

def running_max(iterable):
"Largest of values seen so far."
# running_max([37, 33, 38, 28]) → 37 37 38 38
return accumulate(iterable, func=max)

def running_median(iterable):
"Median of values seen so far."
# running_median([37, 33, 38, 28]) → 37 35 37 35
read = iter(iterable).__next__
lo = [] # max-heap
hi = [] # min-heap the same size as or one smaller than lo
with suppress(StopIteration):
while True:
heappush_max(lo, heappushpop(hi, read()))
yield lo[0]
heappush(hi, heappushpop_max(lo, read()))
yield (lo[0] + hi[0]) / 2

def running_statistics(iterable):
"Aggregate statistics for values seen so far."
# Generate tuples: (size, minimum, median, maximum, mean)
t0, t1, t2, t3 = tee(iterable, 4)
return zip(
count(1),
running_min(t0),
running_median(t1),
running_max(t2),
running_mean(t3),
)


.. doctest::
:hide:

Expand Down Expand Up @@ -1226,10 +1265,6 @@ and :term:`generators <generator>` which incur interpreter overhead.
[(0, 'a'), (1, 'b'), (2, 'c')]


>>> list(running_mean([8.5, 9.5, 7.5, 6.5]))
[8.5, 9.0, 8.5, 8.0]


>>> for _ in loops(5):
... print('hi')
...
Expand Down Expand Up @@ -1789,6 +1824,28 @@ and :term:`generators <generator>` which incur interpreter overhead.
True


>>> list(running_mean([8.5, 9.5, 7.5, 6.5]))
[8.5, 9.0, 8.5, 8.0]
>>> list(running_mean([37, 33, 38, 28]))
[37.0, 35.0, 36.0, 34.0]


>>> list(running_min([37, 33, 38, 28]))
[37, 33, 33, 28]


>>> list(running_max([37, 33, 38, 28]))
[37, 37, 38, 38]


>>> list(running_median([37, 33, 38, 28]))
[37, 35.0, 37, 35.0]


>>> list(running_statistics([37, 33, 38, 28]))
[(1, 37, 37, 37, 37.0), (2, 33, 35.0, 37, 35.0), (3, 33, 37, 38, 36.0), (4, 28, 35.0, 38, 34.0)]


.. testcode::
:hide:

Expand Down
Loading