2016-07-13 7 views
0

habe ich eine Liste wie [('a',2),('a',3),('b',3),('c',2),('b',4)]Summenwerte von als Schlüsselwertpaar in der Liste gespeicherten Tupeln von Schlüssel

Ich möchte alle ähnlichen Schlüssel summieren und erhalten [('a',5),('c',2),('b',7)] in beliebiger Reihenfolge in Ordnung ist.

Gibt es einen besseren Weg, dies zu tun, anstatt ein Wörterbuch zu verwenden. Vorzugsweise etwas mit Liste Verständnis wie [i for j in a for ...]

>>> a = [('a',2),('a',3),('b',3),('c',2),('b',4)] 
>>> from collections import defaultdict 
>>> d = defaultdict(int) 
>>> for i,j in a: 
... d[i] += j 
... 
>>> d 
defaultdict(<type 'int'>, {'a': 5, 'c': 2, 'b': 7}) 
>>> zip(d.keys(),d.values()) 
[('a', 5), ('c', 2), ('b', 7)] 
+0

Gibt es Gründe, warum Sie wollen speziell _list comprehension_ verwenden? – JRodDynamite

+0

@JRodDynamite Ich wollte den Code in Zeilen reduziert werden. Jemand möchte hier nicht viel Code sehen. Es nervt mich auch sehr. –

+1

In Bezug auf Lesbarkeit scheint der Code, den Sie oben geschrieben haben, gut (beste Option, meiner Meinung nach). Vielleicht können Sie es in einer separaten Funktion schreiben, um diese Logik zu trennen. Es reduziert nur die Anzahl der Zeilen in der aktuellen Funktion. – JRodDynamite

Antwort

4

ist dies möglich alternativ mit itertools.groupby in einer Liste Verständnis, obwohl Ihr Ansatz in Ordnung scheint, und es gibt keinen inhärenten Nutzen immer Listenkomprehensionen verwenden. Sich über eine oder zwei Zeilen Code ohne weitere Probleme aufzuregen, ist ein fruchtloses Unterfangen, IMHO. Es kann auch sinnvoll sein, dieses Ergebnis als ein Wörterbuch anstelle einer Liste beizubehalten, falls Sie weitere Zählungen hinzufügen möchten - das Wörterbuch ist die geeignetere Struktur.

Mit dem Ansatz itertools.groupby summieren Sie die sortierten Gruppen basierend auf ersten Tupelelementen.

from itertools import groupby 
from operator import itemgetter 

my_list = [('a',2),('a',3),('b',3),('c',2),('b',4)] 
first = itemgetter(0) 
sums = [(k, sum(item[1] for item in tups_to_sum)) 
     for k, tups_to_sum in groupby(sorted(my_list, key=first), key=first)] 

Ausgänge:

[('a', 5), ('b', 7), ('c', 2)] 

Dies würde offensichtlich funktionieren auch (und vielleicht besser geeignet) als Wörterbuch Verständnis

{(k, sum(item[1] for item in tups_to_sum)) 
      for k, tups_to_sum in groupby(sorted(my_list, key=first), key=first)} 
Verwandte Themen