135 votes

Comment trouver la somme cumulée de nombres dans une liste ?

time_interval = [4, 6, 12]

Je veux résumer les chiffres comme [4, 4+6, 4+6+12] afin d'obtenir la liste t = [4, 10, 22] .

J'ai essayé ce qui suit :

t1 = time_interval[0]
t2 = time_interval[1] + t1
t3 = time_interval[2] + t2
print(t1, t2, t3)  # -> 4 10 22

170voto

askewchan Points 12215

Si vous effectuez beaucoup de travail numérique avec des tableaux comme celui-ci, je vous suggère de numpy qui est doté d'une fonction de somme cumulative cumsum :

import numpy as np

a = [4,6,12]

np.cumsum(a)
#array([4, 10, 22])

Numpy est souvent plus rapide que le pur python pour ce genre de choses, voir en comparaison avec @Ashwini's accumu :

In [136]: timeit list(accumu(range(1000)))
10000 loops, best of 3: 161 us per loop

In [137]: timeit list(accumu(xrange(1000)))
10000 loops, best of 3: 147 us per loop

In [138]: timeit np.cumsum(np.arange(1000))
100000 loops, best of 3: 10.1 us per loop

Mais bien sûr, si c'est le seul endroit où vous utiliserez numpy, cela ne vaut peut-être pas la peine d'en être dépendant.

126voto

Ashwini Chaudhary Points 94431

En Python 2, vous pouvez définir votre propre fonction de générateur comme ceci :

def accumu(lis):
    total = 0
    for x in lis:
        total += x
        yield total

In [4]: list(accumu([4,6,12]))
Out[4]: [4, 10, 22]

Et dans Python 3.2+, vous pouvez utiliser itertools.accumulate() :

In [1]: lis = [4,6,12]

In [2]: from itertools import accumulate

In [3]: list(accumulate(lis))
Out[3]: [4, 10, 22]

29voto

Vani S Points 304

Essayez le itertools.accumulate() fonction.

import itertools  

list(itertools.accumulate([1,2,3,4,5]))
# [1, 3, 6, 10, 15]

27voto

Chris_Rands Points 15161

J'ai fait une analyse comparative des deux meilleures réponses avec Python 3.4 et j'ai constaté que itertools.accumulate est plus rapide que numpy.cumsum dans de nombreuses circonstances, souvent beaucoup plus rapidement. Cependant, comme vous pouvez le constater dans les commentaires, ce n'est pas toujours le cas, et il est difficile d'explorer de manière exhaustive toutes les options. (N'hésitez pas à ajouter un commentaire ou à modifier ce post si vous avez d'autres résultats de benchmark intéressants).

Quelques horaires...

Pour les listes courtes accumulate est environ 4 fois plus rapide :

from timeit import timeit

def sum1(l):
    from itertools import accumulate
    return list(accumulate(l))

def sum2(l):
    from numpy import cumsum
    return list(cumsum(l))

l = [1, 2, 3, 4, 5]

timeit(lambda: sum1(l), number=100000)
# 0.4243644131347537
timeit(lambda: sum2(l), number=100000)
# 1.7077815784141421

Pour les listes plus longues accumulate est environ 3 fois plus rapide :

l = [1, 2, 3, 4, 5]*1000
timeit(lambda: sum1(l), number=100000)
# 19.174508565105498
timeit(lambda: sum2(l), number=100000)
# 61.871223849244416

Si le numpy array n'est pas transformé en list , accumulate est toujours environ 2 fois plus rapide :

from timeit import timeit

def sum1(l):
    from itertools import accumulate
    return list(accumulate(l))

def sum2(l):
    from numpy import cumsum
    return cumsum(l)

l = [1, 2, 3, 4, 5]*1000

print(timeit(lambda: sum1(l), number=100000))
# 19.18597290944308
print(timeit(lambda: sum2(l), number=100000))
# 37.759664884768426

Si l'on place les importations en dehors des deux fonctions et que l'on renvoie quand même un fichier numpy array , accumulate est toujours près de 2 fois plus rapide :

from timeit import timeit
from itertools import accumulate
from numpy import cumsum

def sum1(l):
    return list(accumulate(l))

def sum2(l):
    return cumsum(l)

l = [1, 2, 3, 4, 5]*1000

timeit(lambda: sum1(l), number=100000)
# 19.042188624851406
timeit(lambda: sum2(l), number=100000)
# 35.17324400227517

20voto

wonder.mice Points 1333

Regardez :

a = [4, 6, 12]
reduce(lambda c, x: c + [c[-1] + x], a, [0])[1:]

La sortie se fera (comme prévu) :

[4, 10, 22]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X