2013-01-06 13 views
20

Ich habe eine Liste von Tupeln ähnlich wie diesen:Summe jeder Wert in einer Liste von Tupeln

l = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 0)] 

Ich mag einen einfachen Einzeiler zu schaffen, die mir folgendes Ergebnis geben wird:

r = (25, 20) or r = [25, 20] # don't care if tuple or list. 

r = [0, 0] 
for t in l: 
    r[0]+=t[0] 
    r[1]+=t[1] 

ich bin sicher, es ist etwas sehr einfach, aber ich kann nicht glauben, es:

, die die folgenden gerne tun würde.

Hinweis: Ich schaute auf ähnliche Fragen schon:

How do I sum the first value in a set of lists within a tuple?

How do I sum the first value in each tuple in a list of tuples in Python?

+0

möglich du plicate von [Python element-weise Tupel-Operationen wie sum] (http://stackoverflow.com/questions/497885/python-element-wise-tuple-operations-like-sum) –

+0

@CiroSantilli: Es ist kein Duplikat. Die Frage, die Sie verknüpft haben, funktioniert mit * zwei * Tupeln. Diese Frage nach einer * Liste * von Tupeln. Die Umsetzung ist der wesentliche Teil der Lösung. Obwohl die Antworten in beiden Fällen fast wörtlich funktionieren. Immer noch sind 'a, b'-Tupel und' a_list_of_tuples' unterschiedlich (der Unterschied könnte in der Lösung angezeigt werden, die am effizientesten ist). – jfs

Antwort

46

Verwenden zip() und sum():

In [1]: l = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 0)] 

In [2]: [sum(x) for x in zip(*l)] 
Out[2]: [25, 20] 

oder:

In [4]: map(sum, zip(*l)) 
Out[4]: [25, 20] 

timeit Ergebnisse:

In [16]: l = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 0)]*1000 

In [17]: %timeit [sum(x) for x in zip(*l)] 
1000 loops, best of 3: 1.46 ms per loop 

In [18]: %timeit [sum(x) for x in izip(*l)]  #prefer itertools.izip 
1000 loops, best of 3: 1.28 ms per loop 

In [19]: %timeit map(sum, zip(*l)) 
100 loops, best of 3: 1.48 ms per loop 

In [20]: %timeit map(sum, izip(*l))    #prefer itertools.izip 
1000 loops, best of 3: 1.29 ms per loop 
+0

O_O kann nicht glauben, wie einfach das war, wie hätte ich 'zip' vergessen können? Vielen Dank. Was ist effizienter? die 'map' oder' list-comprehension' Methode? –

+0

@Inbar testen und herausfinden. – Triptych

+1

'map' übertrifft manchmal das Listenverstehen, wenn es mit eingebauten Funktionen verwendet wird. –

2

ich etwas auf die gegebene Antwort hinzufügen möchten:

Wenn ich eine Reihe von dict z.B.

l = [{'quantity': 10, 'price': 5},{'quantity': 6, 'price': 15},{'quantity': 2, 'price': 3},{'quantity': 100, 'price': 2}] 

und ich möchte zwei (oder mehr) Summen der berechneten Menge über die Werte z. Summe der Mengen und der Preis * Menge

ich tun kann:

(total_quantity, total_price) = (
sum(x) for x in zip(*((item['quantity'], 
         item['price'] * item['quantity']) 
         for item in l))) 

Statt:

total_quantity = 0 
total_price = 0 
for item in l: 
    total_quantity += item['quantity'] 
    total_price += item['price'] * item['quantity'] 

Vielleicht ist die erste Lösung weniger lesbar, aber ist mehr "Pythonesque" :)

+1

Was fügt das zu Ashwinis Antwort hinzu? Die Frage ist nicht über eine Liste von Dicts –

+1

Sie haben Recht, aber es fügt etwas über die Verwendung von Summe und zip für komplexe Operationen. Ich war auf der Suche nach so etwas, ich habe diese Antwort gefunden und ich habe sie für mein eigenes Problem benutzt, das über Diktate ging. Daher dachte ich, es wäre schön, meine Lösung mit jemand anderem zu teilen, der mein Problem haben könnte. –

1

Ohne

Reißverschluss mit
sum(e[0] for e in l), sum(e[1] for e in l) 
Verwandte Themen