¿Cuál es la función como sum () pero para la multiplicación? producto()?


206

La sum()función de Python devuelve la suma de números en un iterable.

sum([3,4,5]) == 3 + 4 + 5 == 12

Estoy buscando la función que devuelve el producto en su lugar.

somelib.somefunc([3,4,5]) == 3 * 4 * 5 == 60

Estoy bastante seguro de que existe tal función, pero no puedo encontrarla.

Respuestas:


71

Actualizar:

En Python 3.8, la función prod se agregó al módulo matemático . Ver: math.prod () .

Información anterior: Python 3.7 y anteriores

La función que está buscando se llamaría prod () o product () pero Python no tiene esa función. Entonces, necesitas escribir el tuyo (lo cual es fácil).

Pronunciamiento en prod ()

Si, eso es correcto. Guido rechazó la idea de una función prod () incorporada porque pensó que rara vez era necesaria.

Alternativa con reduce ()

Como sugirió, no es difícil hacer el suyo usando reduce () y operator.mul () :

from functools import reduce  # Required in Python 3
def prod(iterable):
    return reduce(operator.mul, iterable, 1)

>>> prod(range(1, 5))
24

Tenga en cuenta que en Python 3, la función reduce () se movió al módulo functools .

Caso específico: factoriales

Como nota al margen, el principal caso de uso motivador para prod () es calcular factoriales. Ya tenemos soporte para eso en el módulo de matemáticas :

>>> import math

>>> math.factorial(10)
3628800

Alternativa con logaritmos

Si sus datos consisten en flotantes, puede calcular un producto usando sum () con exponentes y logaritmos:

>>> from math import log, exp

>>> data = [1.2, 1.5, 2.5, 0.9, 14.2, 3.8]
>>> exp(sum(map(log, data)))
218.53799999999993

>>> 1.2 * 1.5 * 2.5 * 0.9 * 14.2 * 3.8
218.53799999999998

Tenga en cuenta que el uso de log () requiere que todas las entradas sean positivas.


Es posible que desee agregar que las carrozas en el último ejemplo deben ser positivas . De lo contrario, es posible que deba usar cmath, pero incluso así no funcionará en todos los casos.
Veky

212

En realidad, Guido vetó la idea: http://bugs.python.org/issue1093

Pero, como se señaló en ese número, puede hacer uno con bastante facilidad:

from functools import reduce # Valid in Python 2.6+, required in Python 3
import operator

reduce(operator.mul, (3, 4, 5), 1)

44
Aquí hay un gran ejemplo de dónde hay una "necesidad de esto", para citar a Guido: producto (filtro (Ninguno, [1,2,3, Ninguno])). Esperemos que sea incluido algún día.
the911s

13
¿No es Guido también el tipo al que no le gusta reduce?
Chris Martin

3
Sí, y reducir ya no es ni siquiera una función integrada en Python 3. En mi opinión, no necesitamos que todos los operadores de listas posibles se agreguen a las funciones integrales globales cuando lo haría una biblioteca estándar (o de terceros). Cuantas más incorporaciones tenga, las palabras más comunes quedarán prohibidas como nombres de variables locales.
ojrac

77
Acabo de encontrar esta pepita en la publicación de blog de Guido sobre reduce () . "Ya tenemos sum (); felizmente cambiaría reduce () por producto () ..." . Si alguien quiere solicitar su inclusión product()en la biblioteca estándar, el número de puntos de vista sobre esta pregunta puede ayudar a resolver el caso.
Patrick McElhaney

1
@PatrickMcElhaney Parece que python3 ya se deshizo de la reducción incorporada. Creo que el producto perdió su oportunidad. ;)
ojrac


39

Hay una prod()en numpy que hace lo que estás pidiendo.


3
nota: no admite Python longs (enteros de precisión arbitraria), por lo que np.prod(range(1,13))da la respuesta correcta igual a 12 Pero np.prod(range(1,14))no lo hace.
Jason S

2
@JasonS np.prod(arange(1,14, dtype='object'))?
endolito

1
La math.prod()función hará que esta respuesta sea obsoleta.
Benoît P

Todavía es tedioso tener que importar matemáticas cuando quieres hacer esto de una manera simple. Echo de menos reduce () y el producto rechazado por Guido ().
RCross

25
Numeric.product 

(o

reduce(lambda x,y:x*y,[3,4,5])

)


Quiere una función que pueda cargar desde un módulo o biblioteca, no escribir la función él mismo.
Jeremy L

2
Pero si no hay uno, probablemente todavía quiera la función.
DNS

1
Correcto, pero necesita saber que uno no existe, ya que esa es su pregunta principal.
Jeremy L

2
También debe reducir un valor predeterminado de 1; de lo contrario, fallará en el caso nulo. El producto de una secuencia vacía se define como 1.
Aaron Robson

3
@CraigMcQueen Numeric es (uno de) los predecesores de numpy.
tacaswell

22

Utilizar este

def prod(iterable):
    p = 1
    for n in iterable:
        p *= n
    return p

Dado que no hay una prodfunción incorporada.


66
debes pensar reducir realmente es un anti patrón :)
zweiterlinde

1
Quería saber si existe una función existente que pueda usar.
Jeremy L

Y esta respuesta explica que no hay una.
EBGreen

55
@zweiterlinde: Para principiantes, reduzca los cables a problemas. En este caso, usar lambda a,b: a*b, no es un problema. Pero reducir no se generaliza bien y se abusa de él. Prefiero que los principiantes no lo aprendan.
S.Lott

@ S.Lott Nunca he visto a ningún principiante usar reducir, y mucho menos cualquier otra construcción funcional. Diablos, incluso los programadores "intermedios" generalmente no saben mucho más allá de la comprensión de una lista.
Mateen Ulhaq


2

Quizás no sea un "incorporado", pero lo considero incorporado. de todos modos solo use numpy

import numpy 
prod_sum = numpy.prod(some_list)

¡Eso está peligrosamente cerca de una declaración de "funciona en mi máquina"! Numpy, preciosa que sea, es unequivocaly no una orden interna.
RCross
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.