Was ist die Funktion wie sum () außer für die Multiplikation? Produkt()?

206

Die Python- sum()Funktion gibt die Summe der Zahlen in einer Iterable zurück.

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

Ich suche nach der Funktion, die stattdessen das Produkt zurückgibt.

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

Ich bin mir ziemlich sicher, dass eine solche Funktion existiert, aber ich kann sie nicht finden.

Patrick McElhaney
quelle

Antworten:

71

Aktualisieren:

In Python 3.8 wurde die Prod- Funktion zum Mathematikmodul hinzugefügt . Siehe: math.prod () .

Ältere Informationen: Python 3.7 und früher

Die gesuchte Funktion würde prod () oder product () heißen, aber Python hat diese Funktion nicht. Sie müssen also Ihre eigenen schreiben (was einfach ist).

Aussprache auf prod ()

Ja, das ist richtig. Guido lehnte die Idee einer eingebauten Funktion prod () ab, weil er dachte, dass sie selten benötigt würde.

Alternative mit reduzieren ()

Wie Sie vorgeschlagen haben, ist es nicht schwer, mit redu () und operator.mul () eigene zu erstellen :

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

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

Beachten Sie, dass in Python 3 die Funktion redu () in das functools-Modul verschoben wurde .

Sonderfall: Fakultäten

Nebenbei bemerkt, der primäre motivierende Anwendungsfall für prod () ist die Berechnung von Fakultäten. Dafür haben wir bereits Unterstützung im Mathematikmodul :

>>> import math

>>> math.factorial(10)
3628800

Alternative mit Logarithmen

Wenn Ihre Daten aus Gleitkommazahlen bestehen, können Sie ein Produkt mit sum () mit Exponenten und Logarithmen berechnen :

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

Beachten Sie, dass für die Verwendung von log () alle Eingaben positiv sind.

Raymond Hettinger
quelle
Vielleicht möchten Sie hinzufügen, dass die Floats im letzten Beispiel positiv sein müssen . Andernfalls müssen Sie möglicherweise cmath verwenden, aber selbst dann funktioniert es nicht in allen Fällen.
Veky
212

Eigentlich hat Guido gegen die Idee ein Veto eingelegt: http://bugs.python.org/issue1093

Wie in dieser Ausgabe erwähnt, können Sie jedoch ganz einfach eine erstellen:

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

reduce(operator.mul, (3, 4, 5), 1)
ojrac
quelle
4
Hier ist ein großartiges Beispiel dafür, wo "Bedarf" besteht, um Guido: product (filter (None, [1,2,3, None])) zu zitieren. Hoffentlich wird es eines Tages enthalten sein.
the911s
13
Ist Guido nicht auch der Typ, der nicht mag reduce?
Chris Martin
3
Ja - und Reduzieren ist nicht einmal mehr ein integriertes Element in Python 3. IMO, wir brauchen nicht jeden möglichen Listenoperator, der zu den globalen integrierten Funktionen hinzugefügt wird, wenn eine Standardbibliothek (oder eine Bibliothek eines Drittanbieters) dies tun würde. Je mehr integrierte Funktionen Sie haben, desto häufiger werden Wörter als lokale Variablennamen gesperrt.
Ojrac
7
Habe gerade dieses Nugget in Guidos Blog-Post über reduct () gefunden . "Wir haben bereits sum (); ich würde gerne redu () gegen product () tauschen ..." . Wenn jemand einen Antrag auf Aufnahme product()in die Standardbibliothek stellen möchte , kann die Anzahl der Ansichten zu dieser Frage hilfreich sein.
Patrick McElhaney
1
@PatrickMcElhaney Es hört sich so an, als hätte Python3 das eingebaute Reduzieren bereits beseitigt. Ich denke, das Produkt hat seine Chance verpasst. ;)
Ojrac
41

Es ist kein einziger eingebaut, aber es ist einfach, einen eigenen zu rollen, wie hier gezeigt :

import operator
def prod(factors):
    return reduce(operator.mul, factors, 1)

Siehe Antworten auf diese Frage:

Welches Python-Modul eignet sich zur Datenmanipulation in einer Liste?

fällinde
quelle
8
Wenn Sie Python 3 verwenden, verwenden Sie functools.reduceanstelle von reduce.
Steven Rumbalski
1
Für noch mehr Spaß an Functools:prod = functools.partial(functools.reduce, operator.mul)
Bukzor
39

Es gibt eine prod()Zahl, die das tut, wonach Sie fragen.

Benjamin
quelle
3
Hinweis: Unterstützt keine Python-Longs (Ganzzahlen mit beliebiger Genauigkeit), np.prod(range(1,13))gibt also die richtige Antwort gleich 12! aber np.prod(range(1,14))nicht.
Jason S
2
@ JasonS np.prod(arange(1,14, dtype='object'))?
Endolith
1
Die math.prod()Funktion macht diese Antwort überflüssig.
Benoît P
Es ist immer noch mühsam, Mathematik importieren zu müssen, wenn Sie dies in einem einfachen Einzeiler tun möchten. Ich vermisse redu () und das von Guido abgelehnte Produkt ().
RCross
25
Numeric.product 

( oder

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

)

Steve B.
quelle
Er möchte eine Funktion, die er aus einem Modul oder einer Bibliothek laden kann, ohne die Funktion selbst zu schreiben.
Jeremy L
2
Aber wenn es keinen gibt, will er wahrscheinlich immer noch die Funktion.
DNS
1
Richtig, aber er muss wissen, dass es keine gibt, da dies seine Hauptfrage ist.
Jeremy L
2
Sie müssen auch einen Standardwert von 1 angeben, da dies sonst im Nullfall fehlschlägt. Das Produkt einer leeren Sequenz ist definiert als 1.
Aaron Robson
3
@CraigMcQueen Numeric ist (einer der) Vorgänger von numpy.
Tacaswell
22

Benutze das

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

Da gibt es keine eingebaute prodFunktion.

S.Lott
quelle
6
Sie müssen denken, reduzieren ist wirklich ein Antimuster :)
Funktionenlinde
1
Er wollte wissen, ob eine vorhandene Funktion vorhanden ist, die er verwenden kann.
Jeremy L
Und diese Antwort erklärt, dass es keine gibt.
EBGreen
5
@zweiterlinde: Für Anfänger führt das Reduzieren zu Problemen. In diesem Fall ist die Verwendung lambda a,b: a*bkein Problem. Aber reduzieren verallgemeinert sich nicht gut und wird missbraucht. Ich bevorzuge Anfänger, die es nicht lernen.
S.Lott
@ S.Lott Ich habe noch nie gesehen, dass Anfänger Reduce verwenden, geschweige denn andere funktionale Konstrukte. Selbst "fortgeschrittene" Programmierer wissen normalerweise nicht viel über ein Listenverständnis hinaus.
Mateen Ulhaq
2

Vielleicht kein "eingebautes", aber ich halte es für eingebaut. sowieso nur numpy verwenden

import numpy 
prod_sum = numpy.prod(some_list)
katiex7
quelle
Das kommt einer Aussage "funktioniert auf meiner Maschine" gefährlich nahe! Numpy, obwohl es schön ist, ist eindeutig kein eingebautes.
RCross