<div dir="ltr"><div>Dear all,</div><div><br></div>In Python, I often find myself building lists where each element depends on the last.  This generally means making a for-loop, create an initial list, and appending to it in the loop, or creating a generator-function.  Both of these feel more verbose than necessary.<div><br></div><div>I was thinking it would be nice to be able to encapsulate this common type of operation into a more compact comprehension.</div><div><br></div><div>I propose a new "Reduce-Map" comprehension that allows us to write: </div><div><pre style="font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;word-spacing:0px;text-decoration-style:initial;text-decoration-color:initial;background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:Menlo;font-size:9pt"><pre style="background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:Menlo;font-size:9pt">signal = [math.<span style="color:rgb(204,120,51)">sin</span>(i*<span style="color:rgb(104,151,187)">0.01</span>) + random.<span style="color:rgb(204,120,51)">normalvariate</span>(<span style="color:rgb(104,151,187)">0</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(104,151,187)">0.1</span>) <span style="color:rgb(70,126,183);font-weight:bold">for </span>i <span style="color:rgb(70,126,183);font-weight:bold">in </span><span style="color:rgb(136,136,198)">range</span>(<span style="color:rgb(104,151,187)">1000</span>)]<br>smooth_signal = [average = (<span style="color:rgb(104,151,187)">1</span>-decay)*average + decay*x <span style="color:rgb(70,126,183);font-weight:bold">for </span>x <span style="color:rgb(70,126,183);font-weight:bold">in </span>signal <span style="color:rgb(70,126,183);font-weight:bold">from </span>average=<span style="color:rgb(104,151,187)">0.</span>]</pre></pre></div><div>Instead of:</div><div><pre style="background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:Menlo;font-size:9pt"><pre style="background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:Menlo;font-size:9pt"><pre style="background-color:rgb(43,43,43);color:rgb(169,183,198);font-family:Menlo;font-size:9pt"><span style="color:rgb(70,126,183);font-weight:bold">def </span><span style="font-weight:bold">exponential_moving_average</span>(signal: Iterable[<span style="color:rgb(136,136,198)">float</span>]<span style="color:rgb(204,120,50)">, </span>decay: <span style="color:rgb(136,136,198)">float</span><span style="color:rgb(204,120,50)">, </span>initial_value: <span style="color:rgb(136,136,198)">float</span>=<span style="color:rgb(104,151,187)">0.</span>):<br>    average = initial_value<br>    <span style="color:rgb(70,126,183);font-weight:bold">for </span>xt <span style="color:rgb(70,126,183);font-weight:bold">in </span>signal:<br>        average = (<span style="color:rgb(104,151,187)">1</span>-decay)*average + decay*xt<br>        <span style="color:rgb(70,126,183);font-weight:bold">yield </span>average<br><br>signal = [math.<span style="color:rgb(204,120,51)">sin</span>(i*<span style="color:rgb(104,151,187)">0.01</span>) + random.<span style="color:rgb(204,120,51)">normalvariate</span>(<span style="color:rgb(104,151,187)">0</span><span style="color:rgb(204,120,50)">, </span><span style="color:rgb(104,151,187)">0.1</span>) <span style="color:rgb(70,126,183);font-weight:bold">for </span>i <span style="color:rgb(70,126,183);font-weight:bold">in </span><span style="color:rgb(136,136,198)">range</span>(<span style="color:rgb(104,151,187)">1000</span>)]<br>smooth_signal = <span style="color:rgb(136,136,198)">list</span>(<span style="color:rgb(204,120,51)">exponential_moving_average</span>(signal<span style="color:rgb(204,120,50)">, </span><span style="color:rgb(170,73,38)">decay</span>=<span style="color:rgb(104,151,187)">0.05</span>))</pre></pre></pre></div><div>I've created a complete proposal at: <a href="https://github.com/petered/peps/blob/master/pep-9999.rst">https://github.com/petered/peps/blob/master/pep-9999.rst</a> , (<a href="https://github.com/python/peps/pull/609">and a pull-request</a>) and I'd be interested to hear what people think of this idea.<br></div><div><br></div><div>Combined with the new "last" builtin discussed in the proposal, this would allow u to replace "reduce" with a more Pythonic comprehension-style syntax.  </div><div><br></div><div>- Peter </div></div>