0
#!/usr/bin/python2
s=5              # input any int 
l1=[5,8,2,1,17]  # input some int numbers
l2=[]            # will be out
for i in l1: 
    s+=i
    l2.append(s)
print l1,l2
[5, 8, 2, 1, 17] 
[10, 18, 20, 21, 38]

I would like to replace the above for cycle with listcomprehension. I generally use list comprehensions but I don't know how could I do with the above for cycle.

  • 5
    Don't try to shoehorn everything into list comprehensions just because you like them. If a good old `for` loop is the most readable way to write the code, use a good old `for` loop. If you want a more "functional" style, the operation you need is not a map (= list comprehension), but a [fold](https://stackoverflow.com/questions/10366374/what-is-the-pythonic-equivalent-to-the-fold-function-from-functional-program). Unfortunately folds are a bit more awkward to write in Python than in some other languages. – Thomas Feb 21 '21 at 12:09

4 Answers4

2

Here you can see use of sum(). However I would not prefer it if the list is too long for the repetitive calculations by sum()

>>> s=5
>>> 
>>> l1=[5,8,2,1,17]
>>> [s+sum(l1[:i+1]) for i,x in enumerate(l1)]
[10, 18, 20, 21, 38]
>>> 
lllrnr101
  • 2,288
  • 2
  • 4
  • 15
2

For a list comprehension without using libraries or the overhead of sum(), you could use an internal list to store the accumulator.

l1 = [5,8,2,1,17]
s  = 5
R  = [a.append(a.pop(0)+n) or a[0] for a in [[s]] for n in l1]

print(R)    
[10, 18, 20, 21, 38]

If you're using Python 3.8+ you can use the walrus operator to manage the accumulation:

R = [a := n + (a if i else s) for i,n in enumerate(l1)]
Alain T.
  • 40,517
  • 4
  • 31
  • 51
  • Thank you very much it is very nice trick to accumulate in list comprehension. First time I had to simplify it to two parts:`a=[s]; l2=[a.append(a.pop(0)+n) or a[0] for n in l1]` that I could understand it better. – László Szilágyi Feb 22 '21 at 10:02
1

List comprehensions are much better suited to situations where you generate an output item independently for each input item. Here, having to sum the items makes it rather inconvenient.

You could use itertools.accumulate, though, which is designed to do that by default:

from itertools import accumulate

l1 = [5, 8, 2, 1, 17]
s = 5

l2 = list(accumulate(l1, initial=s))[1:]
print(l2)
# [10, 18, 20, 21, 38]

(Note that we have to exclude the first value, which would be the initial s, as you don't want it in your output.)

Thierry Lathuille
  • 23,663
  • 10
  • 44
  • 50
0

You have the list-comprehension option

res = [s + sum(l1[:i+1]) for i,x in enumerate(l1)]

Or using some libs along with itertools.accumulate

from operator import add
from itertools import accumulate
import numpy as np

res = np.array(list(accumulate(l1, add))) + s
azro
  • 53,056
  • 7
  • 34
  • 70