2017-04-02 3 views
2

Ich habe die folgende Liste von Tupeln: [('a', 1), ('a', 1), ('b', 1), ('c',1), ('a', 1), ('c', 1)]Wie kann ich die Wortzahlausgabe in Python erstellen, indem ich die Reduce-Funktion verwende?

Ich mag würde wissen, ob ich reduce Funktion der Python nutzen können, um sie zu aggregieren und erzeugen die folgende Ausgabe: [('a', 3), ('b', 1), ('c', 2)]

Oder wenn es andere Wege gibt, würde ich möchte auch wissen (Schleife ist in Ordnung)

+0

Wenn Sie es nicht gleichzeitig tun, verwenden Sie am besten eine HashMap mit

+2

Mögliches Duplikat von [Wie summiere Werte von Tupeln, die in Python denselben Namen haben] (http://stackoverflow.com/questions/31430384/how-to-sum-values-of-tuples-that-same-name -in-Python) – manvi77

Antwort

3

Es scheint schwierig zu erreichen mit reduce, denn wenn beide Tupel, die Sie "reduzieren" nicht den gleichen Buchstaben tragen, können Sie das Ergebnis nicht berechnen. Wie kann man ('a',1) und ('b',1) auf ein praktikables Ergebnis reduzieren?

Beste was ich tun konnte war l = functools.reduce(lambda x,y : (x[0],x[1]+y[1]) if x[0]==y[0] else x+y,sorted(l))

es hat mich ('a', 3, 'b', 1, 'c', 1, 'c', 1). So arbeitete es für das erste Element, aber würde mehr als einen Durchlauf benötigen, um die anderen zu tun (Tupel neu erstellen und einen ähnlichen reduce, naja, nicht sehr effizient, um es gelinde auszudrücken!).

Wie auch immer, hier sind zwei Arbeitsweisen es zunächst

tun, mit collections.Counter Zählelemente der gleichen Art:

l = [('a', 1), ('a', 1), ('b', 1), ('c',1), ('a', 1), ('c', 1)] 

import collections 

c = collections.Counter() 
for a,i in l: 
    c[a] += i 

Wir können nicht listcomp verwenden, da jedes Element ein Gewicht hat (auch wenn hier es ist 1)

Ergebnis: ein Wörterbuch: Counter({'a': 3, 'c': 2, 'b': 1})

Zweite Option: verwenden sie itertools.groupby auf der sortierten Liste, Gruppierung nach Namen/Schreiben und Ausführen der Summe auf den ganzen Zahlen die gleichen Buchstaben tragen:

print ([(k,sum(e for _,e in v)) for k,v in itertools.groupby(sorted(l),key=lambda x : x[0])]) 

Ergebnis:

[('a', 3), ('b', 1), ('c', 2)] 
1

Der alternative Ansatz defaultdict Unterklasse und sum Funktion:

import collections 

l = [('a', 1), ('a', 1), ('b', 1), ('c',1), ('a', 1), ('c', 1)] 
d = collections.defaultdict(list) 
for t in l: 
    d[t[0]].append(t[1]) 

result = [(k,sum(v)) for k,v in d.items()] 
print(result) 

Der Ausgang:

[('b', 1), ('a', 3), ('c', 2)] 
Verwandte Themen