2013-05-19 21 views
19

È possibile emulare qualcosa come sum() utilizzando list comprehension?Python - emula sum() utilizzando la comprensione degli elenchi

Per esempio - ho bisogno di calcolare il prodotto di tutti gli elementi in una lista:

list = [1, 2, 3] 
product = [magic_here for i in list] 

#product is expected to be 6 

codice che sta facendo lo stesso:

def product_of(input): 
    result = 1 
    for i in input: 
     result *= i 
    return result 
+0

Possibile duplicato di [Qual è la funzione Python come sum() ma per la moltiplicazione? prodotto()?] (http://stackoverflow.com/questions/595374/whats-the-python-function-like-sum-but-for-multiplication-product) –

risposta

29

No; una lista di comprensione produce una lista che è lunga quanto il suo input. Sarà necessario uno degli altri strumenti funzionali di Python (in particolare reduce() in questo caso) a fold la sequenza in un unico valore.

+3

Grazie per la prima frase. È la risposta che stavo cercando. – StKiller

+0

in Python 3 è il [functools] (https://docs.python.org/3/library/functools.html) modulo – xealits

37
>>> from operator import mul 
>>> nums = [1, 2, 3] 
>>> reduce(mul, nums) 
6 

In Python 3 si vuole è necessario aggiungere questa importazione: from functools import reduce

Implementation Artifact

In Python 2.5/2.6 Si potrebbe utilizzare vars()['_[1]'] per fare riferimento alla lista di comprensione attualmente in costruzione. Questo è orribile e dovrebbe essere mai mai usato ma è la cosa più vicina a ciò che hai menzionato nella domanda (utilizzando un elenco comp per emulare un prodotto).

>>> nums = [1, 2, 3] 
>>> [n * (vars()['_[1]'] or [1])[-1] for n in nums][-1] 
6 
+3

egads, questo è solo ... Io non evento sapere. – joneshf

+2

questo è davvero carino ... Non avevo idea che tu potessi farlo (e nessuna idea quando o perché tu vorresti mai) ... ma fighi lo stesso –

+1

+1 per il tuo approccio ancora più snello per ottenere un risultato grazie il mio ;-) – Patrick

9

La comprensione degli elenchi crea sempre un altro elenco, quindi non è utile combinarli (ad esempio per fornire un numero singolo). Inoltre, non c'è modo di fare un compito nella comprensione delle liste, a meno che tu non sia super subdolo.

L'unica volta che avessi mai visto usando list comprehensions come utile per un metodo di somma è se solo si desidera includere valori specifici nella lista, o se non si dispone di un elenco di numeri:

list = [1,2,3,4,5] 
product = [i for i in list if i % 2 ==0] # only sum even numbers in the list 
print sum(product) 

o un altro esempio ":

# list of the cost of fruits in pence 
list = [("apple", 55), ("orange", 60), ("pineapple", 140), ("lemon", 80)] 
product = [price for fruit, price in list] 
print sum(product) 

modo Super subdolo per fare un incarico in una lista di comprensione

dict = {"val":0} 
list = [1, 2, 3] 
product = [dict.update({"val" : dict["val"]*i}) for i in list] 
print dict["val"] # it'll give you 6! 

... ma questo è orribile :)

+0

+1 per menzionare anche l'ultimo metodo è orribile :) – jamylak

3
>>> reduce(int.__mul__,[1,2,3]) 
6 

C:\Users\Henry>python -m timeit -s "" "reduce(int.__mul__,range(10000))" 
1000 loops, best of 3: 910 usec per loop 

C:\Users\Henry>python -m timeit -s "from operator import mul" "reduce(mul,range(10000))" 
1000 loops, best of 3: 399 usec per loop 

C:\Users\Henry> 
4

Qualcosa di simile a questo:

>>> a = [1,2,3] 
>>> reduce(lambda x, y: x*y, a) 
6 
+1

Penso che intendessi x + y not x * y ... anche se entrambi danno lo stesso risultato per i tuoi dati di test –

0

Trovato la magia su http://code.activestate.com/recipes/436482/.

>>> L=[2, 3, 4] 
>>> [j for j in [1] for i in L for j in [j*i]][-1] 
24 

Dovrebbe essere la logica come il seguente codice.

L=[2, 3, 4] 
P=[] 
for j in [1]: 
    for i in L: 
     for j in [j*i]: 
      P.append(j) 
print(P[-1]) 
+2

Questo è stato contrassegnato come VLQ. Costruisce un'intera lista, quindi prende solo un valore - in modo molto inefficiente e non tecnicamente "emula con la comprensione delle liste" (che è impossibile per i motivi indicati nelle risposte migliori). Questo potrebbe essere un "anti-esempio" ma è così brutto che sono propenso a raccomandare la cancellazione. –

3

mi completano la risposta di Ignacio Vazquez-Abrams con del codice che utilizza l'operatore del reduce Python.

list_of_numbers = [1, 5, 10, 100] 
reduce(lambda x, y: x + y, list_of_numbers) 

che può anche essere scritta come

list_of_numbers = [1, 5, 10, 100] 

def sum(x, y): 
    return x + y 

reduce(sum, list_of_numbers) 

bonus: Python fornisce questa funzionalità nel incorporata sum funzione. Questa è l'espressione più leggibile.

list_of_numbers = [1, 5, 10, 100] 
sum(list_of_numbers) 
Problemi correlati