partial sums problem

G

Gary Herron

The following attempt to get a list of partial sums fails:

s = 0
[((s += t) and s) for t in range(1, 10)]
File "<stdin>", line 1
[((s += t) and s) for t in range(1, 10)]
^
SyntaxError: invalid syntax

What's the best way to get a list of partial sums?

TIA!

kj


Program in C (if that's what you want), or learn Python (if you'd
prefer), but don't try to mix the two.

Python does have "s+=t" as a statement, and it does have list
comprehensions [... for ...] as expressions, but you cannot put a
statement inside an expression.
 
S

Seebs

Python does have "s+=t" as a statement, and it does have list
comprehensions [... for ...] as expressions, but you cannot put a
statement inside an expression.

I've inferred that, in Python, all assignments are by definition
statements, rather than expressions, so they can't be arbitrarily
substituted in for expressions.

It's interesting to see the two ways in which people seem to go
from C's middle ground of expressions and statements; some languages
go to making statements into expressions, others go for even further
narrowing the set of "expressions". I'm not yet sure which I prefer;
both have some appeal in avoiding some of the occasional-complexity that
can make C hard for people to learn. (Meaning, complexity which is
only sometimes at issue, so you have to know about it, but you can't just
use it all the time, so you can't assume it's how things work.)

-s
 
M

MRAB

The following attempt to get a list of partial sums fails:
s = 0
[((s += t) and s) for t in range(1, 10)]
File "<stdin>", line 1
[((s += t) and s) for t in range(1, 10)]
^
SyntaxError: invalid syntax

What's the best way to get a list of partial sums?
Probably:

s = 0
p = []
for t in range(1, 10):
s += t
p.append(s)
 
T

Terry Reedy

The following attempt to get a list of partial sums fails:
s = 0
[((s += t) and s) for t in range(1, 10)]
File "<stdin>", line 1
[((s += t) and s) for t in range(1, 10)]
^
SyntaxError: invalid syntax

What's the best way to get a list of partial sums?

Do not try to do a reduction with a comprehension. Just write clear,
straightforward code that obviously works.

s=[1,2,3,4,5,6]
def cusum(s):
t = 0
for i in s:
t += i
yield t

print(list(cusum(s)))[1, 3, 6, 10, 15, 21]
 
C

Chris Torek

The following attempt to get a list of partial sums fails:
s = 0
[((s += t) and s) for t in range(1, 10)]
File "<stdin>", line 1
[((s += t) and s) for t in range(1, 10)]
^
SyntaxError: invalid syntax

What's the best way to get a list of partial sums?

Well, define "best"; but curiously enough, I wrote this just a few
days ago for other purposes, so here you go, a slightly cleaned-up /
better documented version of what I wrote:

def iaccumulate(vec, op):
"""Do an accumulative operation on a vector (any iterable, really).

The result is a generator whose first call produces vec[0],
second call produces vec[0] op vec[1], third produces
(vec[0] op vec[1]) op vec[2], and so on.

Mostly useful with + and *, probably.
"""
iterable = iter(vec)
acc = iterable.next()
yield acc
for x in iterable:
acc = op(acc, x)
yield acc

def cumsum(vec):
"""Return a list of the cumulative sums of a vector."""
import operator

return list(iaccumulate(vec, operator.add))
 
K

kj

In said:
Do not try to do a reduction with a comprehension. Just write clear,
straightforward code that obviously works.
s=[1,2,3,4,5,6]
def cusum(s):
t = 0
for i in s:
t += i
yield t
print(list(cusum(s)))
[1, 3, 6, 10, 15, 21]


Actually, this is just fine. Thank you!

But it brings up a new question, of an entirely different nature.

It's a recurrent conundrum, actually, and I have not found a good
solution.

Your cusum function is one that I would like to see somewhere in
the standard library (in itertools maybe?). Maybe some future
version of the standard library will have it, or something like it
(I'm thinking of a generalized form which, like reduce, takes a
function and an initial value as arguments).

But in the immediate term, cusum is not part of the standard library.

Where would you put it if you wanted to reuse it? Do you create
a module just for it? Or do you create a general stdlib2 module
with all those workhorse functions that have not made it to the
standard library? Or something else entirely?

(I'm not expecting to get *the* solution from anyone reply; rather,
I'm interested in reading people's take on the question and their
way of dealing with those functions they consider worthy of the
standard library.)

kj
 
E

Ethan Furman

kj said:
I'm interested in reading people's take on the question and their
way of dealing with those functions they consider worthy of the
standard library.)

Well, I have no functions than I'm lobbying to get into the stdlib, but
for all those handy-dandy utility functions, decorators, and classes, I
have a cookbook package that I add them to. Mine currently looks like this:

cookbook
__init__.py
decorators.py
meters.py
simplegeneric.py
utils.py
collections
__init__.py
NamedTuple.py
RecordType.py
 
P

Paul Rubin

kj said:
But in the immediate term, cusum is not part of the standard library.

Where would you put it if you wanted to reuse it? Do you create
a module just for it? Or do you create a general stdlib2 module
with all those workhorse functions that have not made it to the
standard library? Or something else entirely?

In a typical application you'd have a bunch of such utility functions in
a single "utils.py" module or something like that. Java programs use
separate files for each class, so you get zillions of files, but Python
users tend to put more code in each file.

As for the stdlib, the natural places for such a function would be
either itertools or functools, and the function should probably be called
"scan", inspired by this:

http://en.wikibooks.org/wiki/Haskell/List_processing#Scans

Python's version would be like "scanl" with an optional arg to make it
like "scanl1".
 
D

Dennis Lee Bieber

I'm not familiar with that but maybe it's similar.

Take into account that APL is a very operator oriented language, and
functions either one or two arguments...

APL / "reduce" (to start with a known concept)

+/ 1 2 3 4
10

*/ 1 2 3 4
24

APL \ "expand"

+\ 1 2 3 4
3 6 10

*\ 1 2 3 4
2 6 24


-=-=-=-=-
? 52
random integer from 1..52 inclusive (unless base was changed to 0)

20 ? 52
20 random integers, no duplicates.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top