¿Cómo emular sum () utilizando una lista de comprensión?

¿Es posible emular algo como sum () usando la comprensión de lista ?

Por ejemplo, necesito calcular el producto de todos los elementos en una lista:

list = [1, 2, 3] product = [magic_here for i in list] #product is expected to be 6 

Código que está haciendo lo mismo:

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

No; una lista de comprensión produce una lista que es tan larga como su entrada. Necesitará una de las otras herramientas funcionales de Python (específicamente reduce() en este caso) para plegar la secuencia en un solo valor.

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

En Python 3 necesitará agregar esta importación: from functools import reduce

Artefacto de implementación

En Python 2.5 / 2.6 puede usar vars()['_[1]'] para referirse a la lista de comprensión actualmente en construcción. Esto es horrible y nunca debe usarse, pero es lo más parecido a lo que mencionó en la pregunta ( usar una lista comp para emular un producto ).

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

La comprensión de la lista siempre crea otra lista, por lo que no es útil para combinarlos (por ejemplo, para dar un solo número). Además, no hay manera de hacer una tarea en la lista de comprensión, a menos que sea super astuto.

La única vez que he visto usar las comprensiones de listas como útiles para un método de sum es si solo desea incluir valores específicos en la lista, o si no tiene una lista de números:

 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) 

u otro ejemplo “:

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

Una forma super astuta de hacer una tarea en una lista de comprensión

 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! 

… pero eso es horrible 🙂

Algo como esto:

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

Complemento la respuesta de Ignacio Vázquez-Abrams con un código que utiliza el operador de reduce de Python.

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

que también se puede escribir como

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

Bono: Python proporciona esta funcionalidad en la función de sum integrada. Esta es la expresión más legible de imo.

 list_of_numbers = [1, 5, 10, 100] sum(list_of_numbers) 
 >>> 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> 

Encontró la magia en 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 

Debe ser la lógica como el siguiente código.

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

Es posible lograrlo utilizando lambda con comprensión de lista. Ya que no podemos asignar un valor en la comprensión de lista, vamos con lambda

Solución:

 >>> (lambda number_list, sum=0:[sum for number in number_list for sum in [sum + number]][-1])([1, 2, 3, 4, 5]) >>> 15