4

How do I get the cumulative sum of this list using list comprehension:

list_comp=[1,4,9,16] 

Here's what I tried but it prints the double of each item in the list

print([x+x for x in list_comp])

I expect the results to be: list_comp=[1,5,14,30] But I'm getting this:

>> [2, 8, 18, 32]
bit
  • 443
  • 1
  • 7
  • 19
  • 4
    Possible duplicate of [How to find the cumulative sum of numbers in a list?](https://stackoverflow.com/questions/15889131/how-to-find-the-cumulative-sum-of-numbers-in-a-list) – Chris_Rands Dec 02 '17 at 11:27

6 Answers6

10

List comprehensions are for mapping or filtering of lists. They cannot have an internal state, which is what you would need to do this efficiently.

However in Python 3 there is itertools.accumulate for that:

import itertools

print(list(itertools.accumulate([1, 4, 9, 16])))  # [1,5,14,30]
Nils Werner
  • 34,832
  • 7
  • 76
  • 98
2

You can do it like this, by combining slicing and a list comprehension, but it is ungainly to do a cumulative sum efficiently.

comp=[1,4,9,16] 
[sum(comp[:idx+1]) for idx in range(len(comp))]

I would not recommend using this, it recalculates the sum n times!


A proper way to cumsum can be done like this:

def cumsum(seq):
    cumulative = [seq[0]]
    for elt in seq[1:]:
        cumulative.append(cumulative[-1] + elt)
    return cumulative

itertools.accumulate is another way that @NielsWerner demonstrated.


Further efficiency can be found with the numpy library, and the cumsum function of this library.

Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
1

the walrus operator can help to solve this task:

lst = [1,4,9,16] # expected result: [1,5,14,30] 
buf = 0
res = [buf := buf + num for num in lst]
print(res)

[Note : walrus operator is introduced in python 3.8]

Pratik Charwad
  • 697
  • 10
  • 19
lroth
  • 367
  • 1
  • 2
  • 4
0
import numpy as np
a = [1,4,9,16] 

b = np.cumsum(a)
print(list(b))
ababuji
  • 1,683
  • 2
  • 14
  • 39
0

I would like to add one more way of achieving this if you are using Python 2:

def cumulative_sum(seq):
    prev = 0
    result = []
    for item in seq:
        result.append(prev+item)
        prev += item
    return result

for Python 3 i recommend using built in method itertools.accumulate

Manjunath
  • 150
  • 1
  • 6
0

You could try this...

list_comp=[1,4,9,16]
b=[sum(list_comp[0:x+1]) for x in range(0,len(list_comp))]
print(b)