Alright hear me out here:

I've often found that it would be useful for the following type of
expression to be condensed to a one-liner:

def running_average(x_seq):
    averages = []
    avg = 0
    for t, x in enumerate(x_seq):
        avg =  avg*t/(t+1) + x/(t+1)
        averages.append(avg)
    return averages

Because really, there's only one line doing the heavy lifting here, the
rest is kind of boilerplate.

Then I learned about the beautiful and terrible "for x in [value]":

def running_average(x_seq):
    return [avg for avg in [0] for t, x in enumerate(x_seq) for avg in
[avg*t/(t+1) + x/(t+1)]]

Many people find this objectionable because it looks like there are 3 for
loops, but really there's only one: loops 0 and 2 are actually assignments.

**My Proposal**

What if we just officially bless this "using for as a temporary assignment"
arrangement, and allow "for x=value" to mean "assign within the scope of
this for".  It would be identical to "for x in [value]", just more
readable.  The running average function would then be:

def running_average(x_seq):
    return [avg for avg=0 for t, x in enumerate(x_seq) for avg = avg *
t/(t+1) + x / (t+1)]

------ P.S. 1
I am aware of Python 3.8's new "walrus" operator, which would make it:

def running_average(x_seq):
    avg = 0
    return [avg := avg*t/(t+1) + x / (t+1) for t, x in enumerate(x_seq)]

But it seems ugly and bug-prone to be initializing a in-comprehension
variable OUTSIDE the comprehension.

------ P.S. 2
The "for x = value" syntax can achieve things that are not nicely
achievable using the := walrus.  Consider the following example (wherein we
carry forward a "hidden" variable h but do not return it):

y_seq = [y for h=0 for x in x_seq for y, h = update(x, h)]

There's not really a nice way to do this with the walrus because you can't
(as far as I understand) combine it with tuple-unpacking.  You'd have to do
something awkward like:

yh = None, 0
y_seq, _ = zip(*(yh := update(x, yh[1]) for x in x_seq))
------
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/RHW5AUV3C57YOF3REB2HEMYLWLLXSNQT/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to