On Tue, Apr 10, 2018 at 08:12:14PM +0100, Paul Moore wrote:
On 10 April 2018 at 19:25, Peter O'Connor firstname.lastname@example.org 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  for x in values]