[Python-ideas] Proposal: A Reduce-Map Comprehension and a "last" builtin

Danilo J. S. Bellini danilo.bellini at gmail.com
Mon Apr 16 18:02:59 EDT 2018

On 16 April 2018 at 10:49, Peter O'Connor <peter.ed.oconnor at gmail.com>

> Are you able to show how you'd implement the moving average example with
> your package?

Sure! The single pole IIR filter you've shown is implemented here:

I tried:
>     @enable_scan("average")
>     def exponential_moving_average_pyscan(signal, decay, initial=0):
>         yield from ((1-decay)*(average or initial) + decay*x for x in
> signal)
>     smooth_signal_9 = list(exponential_moving_average_pyscan(signal,
> decay=decay))[1:]
> Which almost gave the right result, but seemed to get the initial
> conditions wrong.

I'm not sure what you were expecting. A sentinel as the first "average"

Before the loop begins, this scan-generator just echoes the first input,
like itertools.accumulate.
That is, the first value this generator yields is the first "signal" value,
which is then the first "average" value.

To put an initial memory state, you should do something like this (I've
removed the floating point trailing noise):

>>> from pyscanprev import enable_scan, prepend
>>> @enable_scan("y")
>>> def iir_filter(signal, decay, memory=0):
...     return ((1 - decay) * y + decay * x for x in prepend(memory,
>>> list(iir_filter([1, 2, 3, 2, 1, -1, -2], decay=.1, memory=5))
[5, 4.6, 4.34, 4.206, 3.9854, 3.68686, 3.218174, 2.6963566]

In that example, "y" is the "previous result" (a.k.a. accumulator, or what
had been called "average" here).

Danilo J. S. Bellini
"*It is not our business to set up prohibitions, but to arrive at
conventions.*" (R. Carnap)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180416/ddd984af/attachment-0001.html>

More information about the Python-ideas mailing list