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

Steven D'Aprano steve at pearwood.info
Tue Apr 10 23:41:15 EDT 2018


On Tue, Apr 10, 2018 at 08:12:14PM +0100, Paul Moore wrote:
> On 10 April 2018 at 19:25, Peter O'Connor <peter.ed.oconnor at gmail.com> wrote:
> > Kyle Lahnakoski made a pretty good case for not using itertools.accumulate() earlier in this thread
> 
> I wouldn't call it a "pretty good case". He argued that writing
> *functions* was a bad thing, because the name of a function didn't
> provide all the details of what was going on in the same way that
> explicitly writing the code inline would do. That seems to me to be a
> somewhat bizarre argument - after all, encapsulation and abstraction
> are pretty fundamental to programming. I'm not even sure he had any
> specific comments about accumulate other than his general point that
> as a named function it's somehow worse than writing out the explicit
> loop.

I agree with Paul here -- I think that Kyle's argument is idiosyncratic. 
It isn't going to stop me from writing functions :-)


> > But in a way that more intuitively expresses the intent of the code, it
> > would be great to have more options on the market.
> 
> It's worth adding a reminder here that "having more options on the
> market" is pretty directly in contradiction to the Zen of Python -
> "There should be one-- and preferably only one --obvious way to do
> it".

I'm afraid I'm going to (mildly) object here. At least you didn't 
misquote the Zen as "Only One Way To Do It" :-)

The Zen here is not a prohibition against there being multiple ways to 
do something -- how could it, given that Python is a general purpose 
programming language there is always going to be multiple ways to write 
any piece of code? Rather, it exhorts us to make sure that there are one 
or more ways to "do it", at least one of which is obvious.

And since "it" is open to interpretation, we can legitimately wonder 
whether (for example):

    - for loops
    - list comprehensions
    - list(generator expression)

etc are three different ways to do "it", or three different "it"s. If we 
wish to dispute the old slander that Python has Only One Way to do 
anything, then we can emphasise the similarities and declare them three 
ways; if we want to defend the Zen, we can emphasise the differences and 
declare them to be three different "it"s.

So I think Peter is on reasonable ground to suggest this, if he can make 
a good enough case for it.

Personally, I still think the best approach here is a combination of 
itertools.accumulate, and the proposed name-binding as an expression 
feature:

    total = 0
    running_totals = [(total := total + x) for x in values]
    # alternative syntax
    running_totals = [(total + x as total) for x in values]

If you don't like the dependency on an external variable (or if that 
turns out not to be practical) then we could have:

    running_totals = [(total := total + x) for total in [0] for x in values]


-- 
Steve


More information about the Python-ideas mailing list