I was writing a function in python to extract original values given a list containing cumulative sum values. For eg -

Given : cumulative_sum = [1, 3, 6, 10, 15, 21, 28, 36, 45]
Output : [1, 2, 3, 4, 5, 6, 7, 8, 9]

I came up with two functions A & B and am looking for feedback on them, especially using xrange() vs enumerate().

import numpy as np
cumulative = np.cumsum(range(1,10))

def A(cumulative):
    output = [0] * len(cumulative)
    for i in xrange(len(cumulative)-1):
        output[-(i+1)] = cumulative[-(i+1)] - cumulative[-(i+2)]
    output[0] = cumulative[0]
return output

def B(cumulative):
    output = [0] * len(cumulative)
    for i,e in reversed(list(enumerate(cumulative))):
        output[i]=cumulative[i] - cumulative[i-1]
return output

2 Answers 2


Both aren't great. B is really complicated, which is unnecessary. A has this extra negation:

output[-(i+1)] = cumulative[-(i+1)] - cumulative[-(i+2)]

You could have just used positive indices (why iterate backwards anyway?):

output[i+1] = cumulative[i+1] - cumulative[i]

I think sort of thing is best accomplished with itertools. In particular, there's a pairwise recipe:

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

Which translates directly into what we want to do:

def C(cumulative):
    yield cumulative[0]
    for a, b in pairwise(cumulative):
        yield b-a

This returns a generator, instead of a list, but generators are typically far more useful anyway. I feel that this approach makes it much more explicit what it is you're actually doing: you're yielding the first element, and then the pairwise difference between the rest.


Numpy's element-wise subtraction can be used to leverage the pairwise operation by shifting the cumulative sum.

import numpy as np

x = np.arange(1, 10)     # desired output in OP
x_cumsum = np.cumsum(x)  # given in OP

x_cumsum_shifted = np.insert(np.delete(x_cumsum, -1), 0, 0)

_x = x_cumsum - x_cumsum_shifted  # the desired output in OP

For instance, if x_cumsum = [a, a+b, a+b+c, a+b+c+d],
and x_cumsum_shifted = [0, a, a+b, a+b+c],
therefore x_cumsum - x_cumsum_shifted = [a, b, c, d].


Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.