On 05/04/18 17:52, Peter O'Connor wrote:
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.
I was thinking it would be nice to be able to encapsulate this common type of operation into a more compact comprehension.
I propose a new "Reduce-Map" comprehension that allows us to write:
signal = [math.sin(i*0.01) + random.normalvariate(0, 0.1) for i in range(1000)] smooth_signal = [average = (1-decay)*average + decay*x for x in signal from average=0.]
Ew. This looks magic (and indeed is magic) and uses single equals inside the expression (inviting "=" vs "==" gumbies). I think you are trying to do too much in one go, and something like this is complex enough that it shouldn't be in a comprehension in the first place.
def exponential_moving_average(signal: Iterable[float], decay: float, initial_value: float=0.): average = initial_value for xt in signal: average = (1-decay)*average + decay*xt yield average
signal = [math.sin(i*0.01) + random.normalvariate(0, 0.1) for i in range(1000)] smooth_signal = list(exponential_moving_average(signal, decay=0.05))
Aside from unnecessarily being a generator, this reads better to me!