2016-06-09 14 views
0

Ich bin auf der Suche nach einem Pythonic Weg, um eine große Anzahl von Listen zu durchlaufen und den Index der wiederholten Werte aus einer Liste zu verwenden, um einen Gesamtwert aus den Werten mit dem gleichen Index in einem anderen zu berechnen Liste.Schnelle Komprimierung von mehreren Listen mit Wertaddition

Zum Beispiel sagen, ich habe zwei Listen

a = [ 1, 2, 3, 1, 2, 3, 1, 2, 3] 
b = [ 1, 2, 3, 4, 5, 6, 7, 8, 9] 

Was will ich die eindeutigen Werte in a finden tun, und fügen Sie dann zusammen mit den entsprechenden Werten von b mit dem gleichen Index. Mein Versuch, die ziemlich langsam ist, ist wie folgt:

a1=list(set(a)) 
b1=[0 for y in range(len(a1))] 
    for m in range(len(a)): 
     for k in range(len(a1)): 
      if a1[k]==a[m]: 
       b1[k]+=b[m] 

und ich

a1=[1, 2, 3] 
b1=[12, 15, 18] 

Bitte lassen Sie mich wissen, ob es ein schneller, pythonic Weg, dies zu tun. Dank

Antwort

1

Verwenden Sie die zip() function und ein defaultdict dictionary auf Werte pro eindeutigen Wert zu sammeln:

from collections import defaultdict 
try: 
    # Python 2 compatibility 
    from future_builtins import zip 
except ImportError: 
    # Python 3, already there 
    pass 

values = defaultdict(int) 
for key, value in zip(a, b): 
    values[key] += value 

a1, b1 = zip(*sorted(values.items())) 

zip() paart sich die Werte aus zwei Eingangslisten, jetzt alles, was Sie tun müssen, ist, summieren sich jeder Wert von b pro eindeutigen Wert von a.

Die letzte Zeile entfernt die Schlüssel und Werte aus dem resultierenden Wörterbuch, sortiert diese und fügt nur die Schlüssel und nur die Werte in a1 bzw. b1 ein.

Demo:

>>> from collections import defaultdict 
>>> a = [ 1, 2, 3, 1, 2, 3, 1, 2, 3] 
>>> b = [ 1, 2, 3, 4, 5, 6, 7, 8, 9] 
>>> values = defaultdict(int) 
>>> for key, value in zip(a, b): 
...  values[key] += value 
... 
>>> zip(*sorted(values.items())) 
[(1, 2, 3), (12, 15, 18)] 

Wenn Sie nicht über Ausgabereihenfolge kümmern, können Sie den Anruf sorted() insgesamt sinken.

+0

Das scheint gut zu funktionieren! Ich habe mich gefragt, ob es möglich wäre, eine weitere Stufe der Komplexität hinzuzufügen. Das heißt, eine dritte Liste, sagen wir c = [0,1,0,1,0,1,0,1,0], so dass der Wert nur hinzugefügt wird, wenn c [key] = 1 ?? – MicahJ

+0

@MicahJ: füge einfach 'c' zum ersten' zip() 'hinzu:' Für Schlüssel, Wert, füge zip (a, b, c) hinzu: ', dann füge ein' if add: 'dazwischen ein. –