2012-12-09 32 views
19

Let data = [[3,7,2],[1,4,5],[9,8,7]]Somma dell'elenco di elenchi; restituisce la lista somma

Diciamo che voglio riassumere gli elementi per gli indici di ciascuna lista nella lista, come l'aggiunta di numeri in una colonna della matrice per ottenere una lista unica. Suppongo che tutte le liste di dati abbiano la stessa lunghezza.

print foo(data) 

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

Come posso scorrere l'elenco degli elenchi senza ottenere un errore di indice fuori intervallo? Forse lambda? Grazie!

+0

[Cosa hai provato?] (Http://whathaveyoutried.com/) –

risposta

51

Si potrebbe provare questo:

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] 

Questo utilizza una combinazione di zip e * per decomprimere la lista e poi zip gli elementi in base al loro indice. Quindi usi una list comprehension per iterare attraverso i gruppi di indici simili, sommandoli e ritornando nella loro posizione 'originale'.

Per rendere spero che un po 'più chiaro, qui è ciò che accade quando si scorrere attraverso zip(*l):

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

Nel caso di liste che sono di lunghezza diversa, è possibile utilizzare itertools.izip_longest con una fillvalue di 0 - questo riempie fondamentalmente indici mancanti con 0, che consente di sommare tutti 'colonne':

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] 

In questo caso, qui è che cosa l'iterazione su izip_longest sarà simile:

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

Spiegazione molto chiara e codice conciso. Grazie!! – Albert

+0

@Albert Nessun problema, buona fortuna a tutto! – RocketDonkey

+2

Oppure 'map (sum, zip (* l))' (questo è il mio preferito). – arshajii

0

Questo non dipende sul presupposto che tutte le liste interne (o righe) sono della stessa lunghezza, ma si dovrebbe fare ciò che si vuole:

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

Per qualsiasi matrice (o altro numerica ambizioso) operazioni Consiglierei di guardare in NumPy.

Il campione per risolvere la somma di una matrice lungo l'asse indicato nella sua domanda sarebbe:

>>> 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]) 

Ecco la documentazione del NumPy per la sua funzione di somma: http://docs.scipy.org/doc/numpy/reference/generated/numpy.sum.html#numpy.sum

Soprattutto il secondo argomento è interessante come consente di specificare facilmente ciò che dovrebbe essere riassunto: tutti gli elementi o solo un asse specifico di una matrice potenzialmente n-dimensionale (come).

+0

Grazie per la richiesta. Ho aggiunto un campione. Penserei che questo sarebbe più efficiente in termini di tempo e spazio rispetto a qualsiasi altro campione. – Theuni

+0

Molto bello (e più facile sintassi da digerire rispetto al mio :)). – RocketDonkey

+0

Apprezzato - soprattutto visto che non ho mai usato Numpy prima, ma conosco alcuni ragazzi che fanno il calcolo scientifico e lo usano ampiamente. Ero sorpreso di quanto fosse facile. – 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

questo vi darà la somma per ogni sottoelenco

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

Se si desidera sommare su tutti gli elementi e ottenere solo una somma quindi utilizzare questo

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

Non ti capita di fare il corso di algebra lineare su Coursera, vero? Puoi spiegare perché il secondo funziona? – 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