¿Existe una manera más concisa, eficiente o simplemente pitónica de hacer lo siguiente?
def product(list):
p = 1
for i in list:
p *= i
return p
EDITAR:
De hecho, encuentro que esto es marginalmente más rápido que usar operator.mul:
from operator import mul
# from functools import reduce # python3 compatibility
def with_lambda(list):
reduce(lambda x, y: x * y, list)
def without_lambda(list):
reduce(mul, list)
def forloop(list):
r = 1
for x in list:
r *= x
return r
import timeit
a = range(50)
b = range(1,50)#no zero
t = timeit.Timer("with_lambda(a)", "from __main__ import with_lambda,a")
print("with lambda:", t.timeit())
t = timeit.Timer("without_lambda(a)", "from __main__ import without_lambda,a")
print("without lambda:", t.timeit())
t = timeit.Timer("forloop(a)", "from __main__ import forloop,a")
print("for loop:", t.timeit())
t = timeit.Timer("with_lambda(b)", "from __main__ import with_lambda,b")
print("with lambda (no 0):", t.timeit())
t = timeit.Timer("without_lambda(b)", "from __main__ import without_lambda,b")
print("without lambda (no 0):", t.timeit())
t = timeit.Timer("forloop(b)", "from __main__ import forloop,b")
print("for loop (no 0):", t.timeit())
me da
('with lambda:', 17.755449056625366)
('without lambda:', 8.2084708213806152)
('for loop:', 7.4836349487304688)
('with lambda (no 0):', 22.570688009262085)
('without lambda (no 0):', 12.472226858139038)
('for loop (no 0):', 11.04065990447998)
listcomo nombre de variable ...
+para ese tipo de lista (del mismo modo para producto / *). Ahora me doy cuenta de que Python está tipeado dinámicamente, lo que dificulta las cosas, pero este es un problema resuelto en idiomas sanos con sistemas de tipo estático como Haskell. Pero de todos modos Pythonsolo permite sumtrabajar en números, ya sum(['a', 'b'])que ni siquiera funciona, por lo que nuevamente digo que 0tiene sentido para sumy 1para el producto.

reducerespuestas generan unTypeError, mientras que laforrespuesta en bucle devuelve 1. Este es un error en laforrespuesta en bucle (el producto de una lista vacía no es más de 1 que 17 o 'armadillo').