2012-12-09 7 views
19

Niech data = [[3,7,2],[1,4,5],[9,8,7]]Suma list; zwraca listę sum

Powiedzmy, że chcemy zsumować elementy indeksów każdej listy na liście, takie jak dodawanie liczb w kolumnie macierzy dostać jedną listę. Zakładam, że wszystkie listy w danych są równej długości.

print foo(data) 

    [[3,7,2], 
    [1,4,5], 
    [9,8,7]] 
    _______ 
>>>[13,19,14] 

Jak mogę powtórzyć listę list bez otrzymania błędu poza zakresem? Może lambda? Dzięki!

+0

[Co próbowaliście?] (Http://whathaveyoutried.com/) –

Odpowiedz

51

Można spróbować to:

In [9]: l = [[3,7,2],[1,4,5],[9,8,7]] 

In [10]: [sum(i) for i in zip(*l)] 
Out[10]: [13, 19, 14] 

ten wykorzystuje kombinację zip* rozpakować i listy, a następnie zip elementy według ich indeksu. Następnie używasz rozumienia list do iteracji przez grupy podobnych indeksów, sumując je i powracając w swojej "oryginalnej" pozycji.

miejmy nadzieję uczynić go nieco bardziej jasne, o to co się dzieje, gdy iterację zip(*l):

In [13]: for i in zip(*l): 
    ....:  print i 
    ....:  
    ....:  
(3, 1, 9) 
(7, 4, 8) 
(2, 5, 7) 

W przypadku list, które są nierównej długości, można użyć itertools.izip_longest z fillvalue z 0 - to w zasadzie wypełnia brakujące indeksy z 0, dzięki czemu można podsumować wszystkie kolumny „”:

In [1]: import itertools 

In [2]: l = [[3,7,2],[1,4],[9,8,7,10]] 

In [3]: [sum(i) for i in itertools.izip_longest(*l, fillvalue=0)] 
Out[3]: [13, 19, 9, 10] 

W tym przypadku, o to co Iterowanie nad izip_longest wyglądałby następująco:

In [4]: for i in itertools.izip_longest(*l, fillvalue=0): 
    ...:  print i 
    ...:  
(3, 1, 9) 
(7, 4, 8) 
(2, 0, 7) 
(0, 0, 10) 
+0

Bardzo jasne wyjaśnienie i zwięzły kod. Dzięki!! – Albert

+0

@Albert Bez problemu, powodzenia ze wszystkim! – RocketDonkey

+2

Lub 'map (sum, zip (* l))' (ten jest moim ulubionym). – arshajii

0

To nie zależy na założeniu, że wszystkie wewnętrzne listy (lub wiersze) są tej samej długości, ale powinien robić to, co chcesz:

sum_list = [] 

ncols = len(data[0]) 

for col in range(ncols): 
    sum_list.append(sum(row[col] for row in data)) 


sum_list 
Out[9]: [13, 19, 14] 
7

Dla każdej macierzy (lub innego ambitnego numeryczne) operacji Polecam, patrząc na NumPy.

Próbkę do rozwiązywania sumę szeregu wzdłuż osi pokazanej na swoje pytanie byłoby:

>>> from numpy import array 
>>> data = array([[3,7,2], 
...  [1,4,5], 
...  [9,8,7]]) 
>>> from numpy import sum 
>>> sum(data, 0) 
array([13, 19, 14]) 

Oto dokumentacja NumPy dla jego funkcji Suma: http://docs.scipy.org/doc/numpy/reference/generated/numpy.sum.html#numpy.sum

Zwłaszcza drugi argument jest interesujący jako pozwala łatwo określić, co powinno zostać zsumowane: wszystkie elementy lub tylko konkretna oś tablicy potencjalnie n-wymiarowej (podobnej).

+0

Dzięki za zapytanie. Dodałem próbkę. Sądzę, że będzie to więcej czasu i przestrzeni niż jakakolwiek inna próba. – Theuni

+0

Bardzo fajna (i łatwiejsza do strawienia syntaktyka niż moja :)). – RocketDonkey

+0

Doceniony - szczególnie biorąc pod uwagę, że nigdy wcześniej nie używałam Numpy'ego, ale znam kilku facetów, którzy robią naukowe obliczenia i używają go w znacznym stopniu. Sam byłem zaskoczony, jakie to łatwe. – Theuni

1
>>> data = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] 
>>> for column in enumerate(data[0]): 
...  count = sum([x[column[0]] for x in data]) 
...  print 'Column %s: %d' % (column[0], count) 
... 
Column 0: 3 
Column 1: 6 
Column 2: 9 
6

To daje sumę dla każdego podmenu

data = [[3,7,2],[1,4],[9,8,7,10]] 
list(map(sum, data)) 
[12, 5, 34] 

Jeśli chcesz Podsumowując na wszystkie elementy i dostać tylko jedną sumę następnie użyć tego

data = [[3,7,2],[1,4],[9,8,7,10]] 
sum(sum(data, [])) 
51 
+0

Nie robisz kursu Linear Algebra na Courserze, prawda? Czy możesz wyjaśnić, dlaczego drugi działa? – Parseltongue

0
def sum(L): 
res = list() 
for j in range(0,len(L[0])): 
    tmp = 0 
    for i in range(0,len(L)): 
     tmp = tmp + L[i][j] 
    res.append(tmp) 
return res