2010-07-11 3 views
23

dire que j'ai une liste 2D Python comme ci-dessous:Comment faire la somme des colonnes de la liste 2D?

my_list = [ [1,2,3,4], 
      [2,4,5,6] ] 

je peux obtenir les totaux des lignes avec une compréhension de la liste:

row_totals = [ sum(x) for x in my_list ] 

Puis-je obtenir les totaux des colonnes sans une double boucle for? -À-dire, pour obtenir cette liste:

[3,6,8,10] 

Répondre

29

Utilisez zip

col_totals = [ sum(x) for x in zip(*my_list) ] 
+0

J'aime ça car ça ne suppose pas 2 lignes. – Marty

+0

+1 zip (* my_list) – Medorator

5
[x + y for x, y in zip(*my_list)] 
+1

La * my_list est une astuce. – Metalshark

+0

C'est très bien. Je ne l'ai jamais vu avant ... – Marty

16
>>> map(sum,zip(*my_list)) 
[3, 6, 8, 10] 

Ou les itertools équivalents

>>> from itertools import imap, izip 
>>> imap(sum,izip(*my_list)) 
<itertools.imap object at 0x00D20370> 
>>> list(_) 
[3, 6, 8, 10] 
+3

Et nous avons un gagnant de code golf! – Metalshark

+0

Un sorcier parmi nous –

7

Solution map(sum,zip(*my_list)) est le plus rapide. Toutefois, si vous devez conserver la liste, [x + y for x, y in zip(*my_list)] est le plus rapide.

Le test a été réalisé en Python 3.1.2 64 bits.

>>> import timeit 
>>> my_list = [[1, 2, 3, 4], [2, 4, 5, 6]] 
>>> t1 = lambda: [sum(x) for x in zip(*my_list)] 
>>> timeit.timeit(t1) 
2.5090877081503606 
>>> t2 = lambda: map(sum,zip(*my_list)) 
>>> timeit.timeit(t2) 
0.9024796603792709 
>>> t3 = lambda: list(map(sum,zip(*my_list))) 
>>> timeit.timeit(t3) 
3.4918002495520284 
>>> t4 = lambda: [x + y for x, y in zip(*my_list)] 
>>> timeit.timeit(t4) 
1.7795929868792655 
+0

Bon à savoir. Merci d'avoir fait le test de vitesse. – Metalshark

Questions connexes