Qual è la funzione come sum () ma per la moltiplicazione? Prodotto()?


206

La sum()funzione di Python restituisce la somma dei numeri in un iterabile.

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

Sto cercando invece la funzione che restituisce il prodotto.

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

Sono abbastanza sicuro che esista una tale funzione, ma non riesco a trovarla.

Risposte:


71

Aggiornare:

In Python 3.8, la funzione prod è stata aggiunta al modulo matematico . Vedi: math.prod () .

Informazioni precedenti: Python 3.7 e precedenti

La funzione che stai cercando si chiamerebbe prod () o product () ma Python non ha quella funzione. Quindi, devi scrivere il tuo (che è facile).

Pronuncia su prod ()

Sì, è giusto. Guido respinse l'idea di una funzione prod () incorporata perché pensava che raramente fosse necessaria.

Alternativa con reduce ()

Come hai suggerito, non è difficile crearne uno tuo usando riduci () e operator.mul () :

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

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

Nota, in Python 3, la funzione di riduzione () è stata spostata nel modulo functools .

Caso specifico: fattoriali

Come nota a margine, il caso d'uso motivante principale per prod () è calcolare fattoriali. Abbiamo già il supporto per questo nel modulo di matematica :

>>> import math

>>> math.factorial(10)
3628800

Alternativa ai logaritmi

Se i tuoi dati sono costituiti da float, puoi calcolare un prodotto usando sum () con esponenti e logaritmi:

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

Nota, l'uso di log () richiede che tutti gli input siano positivi.


Potresti voler aggiungere che i float nell'ultimo esempio devono essere positivi . Altrimenti, potresti dover usare cmath, ma anche in questo caso non funzionerà davvero in tutti i casi.
Veky,

212

In realtà, Guido ha posto il veto sull'idea: http://bugs.python.org/issue1093

Ma, come notato in questo numero, puoi crearne uno abbastanza facilmente:

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

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

4
Ecco un ottimo esempio di dove c'è un "bisogno di questo" per citare Guido: prodotto (filtro (Nessuno, [1,2,3, Nessuno])). Spero che un giorno sia incluso.
the911s

13
Guido non è anche il ragazzo a cui non piace reduce?
Chris Martin,

3
Sì - e ridurre non è più nemmeno un builtin in Python 3. IMO, non abbiamo bisogno di ogni possibile operatore di lista aggiunto ai builtin globali quando una libreria standard (o di terze parti) lo farebbe. Più builtin hai, più le parole comuni diventano off-limits come nomi di variabili locali.
ojrac,

7
Ho appena trovato questa pepita nel post sul blog di Guido su reduce () . "Abbiamo già la somma (); sarei felice di scambiare la riduzione () per il prodotto () ..." . Se qualcuno desidera presentare una petizione per l'inclusione product()nella libreria standard, il numero di visualizzazioni su questa domanda può essere utile.
Patrick McElhaney,

1
@PatrickMcElhaney Sembra che python3 abbia già eliminato il riduttore incorporato. Penso che il prodotto abbia perso l'occasione. ;)
ojrac,


39

C'è un prod()intorpidito che fa quello che stai chiedendo.


3
nota: non supporta i long di Python (interi di precisione arbitrari) quindi np.prod(range(1,13))fornisce la risposta corretta pari a 12! ma np.prod(range(1,14))non lo fa.
Jason S,

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

1
La math.prod()funzione renderà questa risposta obsoleta.
Benoît P,

Ancora noioso dover importare la matematica quando vuoi farlo in un semplice one-liner. Mi manca ridurre () e il prodotto rifiutato da Guido ().
RCross,

25
Numeric.product 

( o

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

)


Vuole una funzione che può caricare da un modulo o una libreria, non scrivendo la funzione da solo.
Jeremy L,

2
Ma se non ce n'è uno, probabilmente vuole ancora la funzione.
DNS,

1
Giusto, ma ha bisogno di sapere che uno non esiste, poiché questa è la sua domanda principale.
Jeremy L,

2
Devi anche ridurre un valore predefinito di 1, altrimenti fallirà nel caso nullo. Il prodotto di una sequenza vuota è definito come 1.
Aaron Robson

3
@CraigMcQueen Numereric è (uno dei) predecessori di numpy.
Tacaswell,

22

Usa questo

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

Dal momento che non esiste una prodfunzione integrata.


6
devi pensare che ridurre è davvero un antipasto :)
zweiterlinde,

1
Voleva sapere se esiste una funzione esistente che può usare.
Jeremy L,

E questa risposta spiega che non ce n'è uno.
EBGreen

5
@zweiterlinde: per i principianti, ridurre i problemi. In questo caso, usando lambda a,b: a*b, non è un problema. Ma ridurre non si generalizza bene e viene maltrattato. Preferisco i principianti non impararlo.
S. Lott,

@ S.Lott Non ho mai visto ridursi l'uso di principianti, tanto meno qualsiasi altro costrutto funzionale. Diamine, anche i programmatori "intermedi" di solito non sanno molto oltre la comprensione di un elenco.
Mateen Ulhaq,


2

Forse non è un "builtin", ma lo considero incorporato. comunque basta usare numpy

import numpy 
prod_sum = numpy.prod(some_list)

Questo è pericolosamente vicino a un'affermazione "funziona sulla mia macchina"! Numpy, per quanto adorabile, non è inequivocabile, non è incorporato.
RCross,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.