2012-10-21 33 views
6

Sto provando ad associare un gruppo di elementi in una lista per creare un oggetto finale, in un modo che è analogo a fare una somma di oggetti. Sto cercando di utilizzare una semplice variante su reduce dove consideri un elenco di coppie piuttosto che un elenco semplice per farlo. Voglio fare qualcosa sulla falsariga di:usando Python riduci su un elenco di coppie

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

tranne vorrei aggiungere ulteriori informazioni alla somma che è specifico per ogni elemento della lista dei numeri nums. Ad esempio, per ogni coppia (a, b) nell'elenco, eseguire la somma di (a + b):

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

Questo non funziona:

>>> 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 

Perché non funziona? So che posso codificare nums come un elenco semplice - non è questo il punto - voglio solo essere in grado di creare un'operazione di riduzione che può scorrere su un elenco di coppie, o su due elenchi della stessa lunghezza contemporaneamente e informazioni sul pool da entrambe le liste. Grazie.

+0

Vuoi il risultato della riducono ad essere una tupla? –

+0

Devi usare ridurre? Preferisco la semplice somma (x [0] + x [1] per x in nums) – cerealy

risposta

6

Guardando il lambda passato a reduce:

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

Il valore restituito da f verrà passato come parametro a un'altra invocazione di f. Ma mentre f si aspetta che i suoi parametri siano paia, il valore che restituisce è un int. Devi fare in modo che questa funzione restituisca anche una coppia. Per esempio, questo potrebbe riassumere i lati sinistro e destro separatamente:

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

Un'altra cosa che puoi fare è trattare il valore accumulato in modo diverso dagli elementi della lista: è possibile effettuare il valore accumulato un int, mentre gli elementi della lista sono coppie. Se si esegue questa operazione, è necessario passare l'argomento initializer-reduce, in modo che l'accumulatore è inizializzato correttamente a un int:

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

C'è un modo per ottenere un iteratore da una riduzione rispetto alle coppie? Qualcosa di analogo a 'enumerate (mylist)' per le liste, dove restituisce non solo l'elemento corrente ma anche la sua posizione nell'elenco. Il 'lambda' in' reduce' può accedere al numero della coppia utilizzata nell'esempio sopra? – user248237dfsf

+0

@ user248237 È possibile utilizzare 'enumerate (mylist)' come input per 'reduce'. – interjay