2012-10-21 9 views
6

Ich versuche, eine Reihe von Elementen in einer Liste zu paaren, um ein endgültiges Objekt zu erstellen, in einer Weise analog zu einer Summe von Objekten. Ich versuche, eine einfache Variante auf reduce zu verwenden, wo Sie eine Liste von Paaren eher als eine flache Liste zu diesem Zweck betrachten. Ich möchte von etwas entlang der Linien tun:mit Python reduzieren über eine Liste von Paaren

nums = [1, 2, 3] 
reduce(lambda x, y: x + y, nums) 

außer ich zusätzliche Informationen zu der Summe hinzufügen möchten, die nums in der Liste der Nummern für jedes Element spezifisch ist. Zum Beispiel für jedes Paar (a, b) in der Liste, die Summe als (a + b) ausgeführt wird:

nums = [(1, 0), (2, 5), (3, 10)] 
reduce(lambda x, y: (x[0]+x[1]) + (y[0]+y[1]), nums) 

Dies funktioniert nicht:

>>> reduce(lambda x, y: (x[0]+x[1]) + (y[0]+y[1]), nums) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 1, in <lambda> 
TypeError: 'int' object is unsubscriptable 

Warum funktioniert es nicht? Ich weiß, dass ich nums als eine flache Liste kodieren kann - das ist nicht der Punkt - Ich möchte nur in der Lage sein, eine Reduce-Operation zu erstellen, die über eine Liste von Paaren oder über zwei Listen der gleichen Länge gleichzeitig und Pool-Informationen von iterieren kann beide Listen. Vielen Dank.

+0

Wollen Sie das Ergebnis der Verringerung ein Tupel zu sein? –

+0

Müssen Sie reduzieren? Ich bevorzuge die einfache Summe (x [0] + x [1] für x in Zahlen) – cerealy

Antwort

6

Mit Blick auf dem Lambda Sie reduce geben:

f = lambda x, y: (x[0]+x[1]) + (y[0]+y[1]) 

Der Wert von f zurückgegeben wird als Parameter an einem anderen Aufruf von f weitergegeben werden. Aber während f erwartet, dass seine Parameter Paare sind, ist der Wert, den es zurückgibt, ein int. Sie müssen diese Funktion auch ein Paar zurückgeben lassen. Zum Beispiel würde dies separat mit der linken und der rechten Seite zusammenzufassen:

>>> nums = [(1, 0), (2, 5), (3, 10)] 
>>> reduce(lambda x, y: (x[0] + y[0], x[1] + y[1]), nums) 
(6, 15) 

Eine andere Sache, die Sie tun können, um den akkumulierten Wert unterschiedlich von den Listenelementen zu behandeln: Sie können der akkumulierte Wert ein int, während die Listenelemente machen sind Paare. Wenn Sie dies tun, müssen Sie das initializer Argument reduce passieren, so dass der Akku richtig an eine int initialisiert wird:

>>> nums = [(1, 0), (2, 5), (3, 10)] 
>>> reduce(lambda acc, y: acc + y[0] + y[1], nums, 0) 
21 
+0

Gibt es eine Möglichkeit, nur einen Iterator von reduzieren über die Paare zu bekommen? Etwas analog zu 'enumerate (mylist)' für Listen, wo es nicht nur das aktuelle Element, sondern auch seine Position in der Liste zurückgibt. Kann das "lambda" in "reduce" auf die Nummer des im obigen Beispiel verwendeten Paars zugreifen? – user248237dfsf

+0

@ user248237 Sie können 'enumerate (mylist)' als Eingabe zum Reduzieren verwenden. – interjay

Verwandte Themen