8

i'm trying to sum consecutive numbers in a list while keeping the first one the same.

so in this case 5 would stay 5, 10 would be 10 + 5 (15), and 15 would be 15 + 10 + 5 (30)

x = [5,10,15]
y = []

for value in x:
   y.append(...)

print y

[5,15,30]
O.rka
  • 29,847
  • 68
  • 194
  • 309

4 Answers4

13

You want itertools.accumulate() (added in Python 3.2). Nothing extra needed, already implemented for you.

In earlier versions of Python where this doesn't exist, you can use the pure python implementation given:

def accumulate(iterable, func=operator.add):
    'Return running totals'
    # accumulate([1,2,3,4,5]) --> 1 3 6 10 15
    # accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120
    it = iter(iterable)
    total = next(it)
    yield total
    for element in it:
        total = func(total, element)
        yield total

This will work perfectly with any iterable, lazily and efficiently. The itertools implementation is implemented at a lower level, and therefore even faster.

If you want it as a list, then naturally just use the list() built-in: list(accumulate(x)).

Gareth Latty
  • 86,389
  • 17
  • 178
  • 183
6
y = [sum(x[:i+1]) for i in range(len(x))]
Brent Washburne
  • 12,904
  • 4
  • 60
  • 82
  • 4
    This requires the creation of a ton of sublists, and only works on sequences, not arbitrary iterables. It's also reinventing the wheel in 3.2+. – Gareth Latty Jun 12 '13 at 20:46
  • 2
    @draconisthe0ry: Beware of the performance characteristics of this approach as it becomes quite slow when the list is long. Not only does it create `len(x)` sublists, it sums each sublist each time, rather than adding the latest value to the running sum. Lattyware's answer is the pythonic solution. – Steven Rumbalski Jun 12 '13 at 21:18
4

With numpy.cumsum:

In[1]: import numpy as np
In[2]: x = [5,10,15]
In[3]: x = np.array(x)
In[4]: y = x.cumsum()
In[5]: y
Out[6]: array([ 5, 15, 30])

I am using Python 3.4

hurrdrought
  • 476
  • 1
  • 4
  • 14
1

As in sum all the elements up to the element you're on?

x = [5,10,15]
y = [sum(x[:i+1]) for i in range(len(x))]
will
  • 10,260
  • 6
  • 46
  • 69