Apa fungsi seperti jumlah () tetapi untuk perkalian? produk()?

206

sum()Fungsi Python mengembalikan jumlah angka dalam iterable.

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

Saya mencari fungsi yang mengembalikan produk sebagai gantinya.

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

Saya cukup yakin fungsi seperti itu ada, tetapi saya tidak dapat menemukannya.

Patrick McElhaney
sumber

Jawaban:

71

Memperbarui:

Dalam Python 3.8, fungsi prod ditambahkan ke modul matematika . Lihat: math.prod () .

Info yang lebih lama: Python 3.7 dan sebelumnya

Fungsi yang Anda cari akan disebut prod () atau product () tetapi Python tidak memiliki fungsi itu. Jadi, Anda perlu menulis sendiri (yang mudah).

Pengumuman pada prod ()

Ya itu betul. Guido menolak ide untuk fungsi built-in prod () karena dia pikir itu jarang dibutuhkan.

Alternatif dengan mengurangi ()

Seperti yang Anda sarankan, tidak sulit untuk membuat Anda sendiri menggunakan reduce () dan operator.mul () :

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

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

Catatan, dalam Python 3, fungsi pengurangan () dipindahkan ke modul functools .

Kasus khusus: faktorial

Sebagai catatan, kasus penggunaan motivasi utama untuk prod () adalah untuk menghitung faktorial. Kami sudah memiliki dukungan untuk itu dalam modul matematika :

>>> import math

>>> math.factorial(10)
3628800

Alternatif dengan logaritma

Jika data Anda terdiri dari float, Anda dapat menghitung produk menggunakan jumlah () dengan eksponen dan logaritma:

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

Catatan, penggunaan log () mensyaratkan bahwa semua input positif.

Raymond Hettinger
sumber
Anda mungkin ingin menambahkan bahwa mengapung dalam contoh terakhir harus positif . Kalau tidak, Anda mungkin harus menggunakan cmath, tetapi meskipun begitu itu tidak akan benar-benar berfungsi dalam semua kasus.
Veky
212

Sebenarnya, Guido memveto gagasan: http://bugs.python.org/issue1093

Tetapi, seperti disebutkan dalam masalah itu, Anda dapat membuatnya dengan mudah:

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

reduce(operator.mul, (3, 4, 5), 1)
ojrac
sumber
4
Berikut adalah contoh yang bagus di mana ada "kebutuhan untuk ini," untuk mengutip Guido: product (filter (Tidak, [1,2,3, Tidak ada]))). Semoga itu akan dimasukkan suatu hari nanti.
the911s
13
Bukankah Guido juga pria yang tidak suka reduce?
Chris Martin
3
Yap - dan mengurangi bahkan tidak lagi merupakan builtin di Python 3. IMO, kita tidak perlu setiap operator daftar yang mungkin ditambahkan ke builtin global ketika perpustakaan standar (atau pihak ketiga) akan melakukannya. Semakin banyak bawaan Anda, kata-kata yang lebih umum menjadi terlarang sebagai nama variabel lokal.
ojrac
7
Baru saja menemukan nugget ini di posting blog Guido tentang mengurangi () . "Kami sudah memiliki jumlah (); Saya akan dengan senang hati memperdagangkan pengurangan () untuk produk () ..." . Jika ada yang ingin mengajukan petisi untuk dimasukkan product()dalam pustaka standar, jumlah tampilan pada pertanyaan ini dapat membantu membuat kasus tersebut.
Patrick McElhaney
1
@ PatrickMcElhaney Kedengarannya seperti python3 sudah menyingkirkan mengurangi builtin. Saya pikir produk melewatkan peluangnya. ;)
ojrac
41

Tidak ada satu built-in, tetapi mudah untuk roll sendiri, seperti yang ditunjukkan di sini :

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

Lihat jawaban untuk pertanyaan ini:

Modul Python mana yang cocok untuk manipulasi data dalam daftar?

zweiterlinde
sumber
8
Jika menggunakan Python 3 gunakan functools.reducebukan reduce.
Steven Rumbalski
1
Untuk kesenangan fungsi lainnya:prod = functools.partial(functools.reduce, operator.mul)
bukzor
39

Ada prod()numpy yang melakukan apa yang Anda minta.

Benjamin
sumber
3
Catatan: tidak mendukung Python (bilangan bulat presisi arbitrer) jadi np.prod(range(1,13))berikan jawaban yang benar sama dengan 12! tetapi np.prod(range(1,14))tidak.
Jason S
2
@JasonS np.prod(arange(1,14, dtype='object'))?
endolith
1
The math.prod()Fungsi akan membuat jawaban ini usang.
Benoît P
Masih membosankan harus mengimpor matematika ketika Anda ingin melakukan ini dalam satu kalimat sederhana. Saya rindu mengurangi () dan produk yang ditolak Guido ().
RCross
25
Numeric.product 

( atau

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

)

Steve B.
sumber
Dia menginginkan fungsi yang bisa dia muat dari modul atau perpustakaan, bukan menulis fungsi itu sendiri.
Jeremy L
2
Tetapi jika tidak ada, dia mungkin masih menginginkan fungsinya.
DNS
1
Benar, tetapi dia perlu tahu bahwa tidak ada, karena itu pertanyaan utamanya.
Jeremy L
2
Anda juga harus memberi pengurangan nilai default 1 jika tidak maka akan gagal dalam kasus nol. Produk dari urutan kosong didefinisikan sebagai 1.
Aaron Robson
3
@CraigMcQueen Numeric adalah (salah satu) pendahulu numpy.
tacaswell
22

Gunakan ini

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

Karena tidak ada prodfungsi bawaan.

S.Lott
sumber
6
Anda harus berpikir mengurangi benar-benar adalah antipattern :)
zweiterlinde
1
Dia ingin tahu apakah ada fungsi yang ada yang bisa dia gunakan.
Jeremy L
Dan jawaban ini menjelaskan bahwa tidak ada.
EBGreen
5
@ zweiterlinde: Untuk pemula, kurangi prospek ke masalah. Dalam hal ini, menggunakan lambda a,b: a*b, itu bukan masalah. Tetapi mengurangi tidak menyamaratakan dengan baik, dan disalahgunakan. Saya lebih suka pemula tidak mempelajarinya.
S.Lott
@ S.Lott Saya belum pernah melihat ada pemula menggunakan mengurangi, apalagi konstruksi fungsional-esque lainnya. Heck, bahkan programmer "perantara" biasanya tidak tahu banyak di luar pemahaman daftar.
Mateen Ulhaq
2

Mungkin bukan "builtin", tapi saya menganggapnya builtin. lagian gunakan saja numpy

import numpy 
prod_sum = numpy.prod(some_list)
katiex7
sumber
Itu sangat dekat dengan pernyataan "bekerja pada mesin saya"! Numpy, cantik meskipun, tidak tegas bukan builtin.
RCross