6

I am trying to write a function which maps elements of a list to get sum of the element and the previous elements in the list in a functional style using python e.g. :

func([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) = [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

I have tried using recursion, but get RuntimeError: maximum recursion depth exceeded with a long list.:

def recursion_way(inlist, accu, summ):
    if len(inlist) == 0:
         return accu
    else:
        return recursion_way(inlist[1:], accu + [summ + inlist[0]], summ + inlist[0])
5
  • Could you post the function that you're using? Commented Dec 5, 2012 at 17:04
  • 1
    @user1879805: You can edit the question and add your recursion there :) (it'll be much clearer than in the comments) Commented Dec 5, 2012 at 17:07
  • @Martijn Pieters: You're absolutely right... I deleted my comment. The recursion_way is working fine for just 10 elements (the day I learn to read, I'll conquer the world!!) :) Commented Dec 5, 2012 at 17:11
  • @user1879805 Just so that you know, the maximum recursion limit by default in python is 1000. Commented Dec 5, 2012 at 17:13
  • @Trufa: default recursion limit - it's reconfigurable at runtime. Commented Dec 5, 2012 at 17:16

6 Answers 6

7

Does a comprehension count?

>>> [sum(l[:i]) for i, _ in enumerate(l)]
[0, 0, 1, 3, 6, 10, 15, 21, 28, 36]

or perhaps using reduce:

reduce(
    lambda (sums, last), x: (sums+[x+last], x+last),
    l, ([], 0)
)[0]

Or another way:

reduce(lambda sums,x: sums+[x+sums[-1]], l[1:], l[:1])
Sign up to request clarification or add additional context in comments.

Comments

3

How about reduce? Slow, but interesting, imo.

def func(p):
    for i in xrange(1, len(p)+1):
        yield reduce(lambda x, y: x + y, p[0:i])

>>> list(func(p))
[0, 1, 3, 6, 10, 15, 21, 28, 36, 45]

2 Comments

The for loop uses mutable data and as such probably doesn't qualify as "functional programming".
Your reduce(lambda x, y: x + y, p[0:i]) is the same as sum(p[:i]), which IMO is much more readable
1

Can you use numpy?

import numpy
numpy.cumsum([0,1,2,3,4,5,6,7,8,9])
array([ 0,  1,  3,  6, 10, 15, 21, 28, 36, 45])

2 Comments

NameError: name 'cumsum' is not defined
Changed my answer to use numpy
1

Here is cumulative sum done in the style of functional programming:

def func(l):
   if len(l) < 2: return l
   sub = func(l[:-1])
   return sub + [sub[-1] + l[-1]]

print func([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

Comments

1

Here's what I got, using recursion:

def f(L, n=0):
    # If the list is empty, that means we went through all the elements there
    if len(L)>0:
        # n is the last element in the sum list. Add to it the first remaining element
        n = n+L[0]
        # Return a list containing the newest item and those of the remaining elements
        return [n] + f(L[1:], n)
    else:
        # It it is empty, there are no more sums to calculate
        return []

Comments

-2
l = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
reduce(lambda x, y: x+y, l)

1 Comment

You've implemented sum, not the "rolling sum" the OP is looking for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.