Sum () gibi ama çarpma işlevi nedir? ürün()?


206

Python sum()işlevi yinelenebilir bir sayıdaki toplamları döndürür.

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

Bunun yerine ürünü döndüren işlevi arıyorum.

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

Böyle bir işlevin var olduğundan eminim, ancak bulamıyorum.

Yanıtlar:


71

Güncelleme:

Python 3.8'de, prod fonksiyonu math modülüne eklendi . Bkz . Math.prod () .

Eski bilgiler: Python 3.7 ve öncesi

Aradığınız işleve prod () veya product () denir, ancak Python'un bu işlevi yoktur. Yani, kendi yazmanız gerekir (ki bu kolay).

Prod () ile ilgili duyuru

Evet bu doğru. Guido , yerleşik bir prod () işlevi fikrini reddetti çünkü nadiren gerekli olduğunu düşündü.

Reduce () ile alternatif

Önerdiğiniz gibi, reduce () ve operator.mul () kullanarak kendi hesabınızı oluşturmak zor değildir :

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

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

Python 3'te reduce () işlevinin functools modülüne taşındığını unutmayın .

Özel durum: Faktöriyeller

Bir yan not olarak, prod () için birincil motive edici kullanım örneği faktöriyelleri hesaplamaktır. Matematik modülünde bunun için zaten desteğimiz var :

>>> import math

>>> math.factorial(10)
3628800

Logaritma ile alternatif

Verileriniz şamandıralardan oluşuyorsa, üs ve logaritmalarla sum () kullanarak bir ürünü hesaplayabilirsiniz :

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

Log () kullanımı, tüm girişlerin pozitif olmasını gerektirir.


Son örnekteki şamandıraların pozitif olması gerektiğini eklemek isteyebilirsiniz . Aksi takdirde, cmath kullanmak zorunda kalabilirsiniz, ancak o zaman bile her durumda gerçekten işe yaramaz.
Veky

212

Aslında, Guido fikri veto etti: http://bugs.python.org/issue1093

Ancak, bu sayıda belirtildiği gibi, kolayca yapabilirsiniz:

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

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

4
Guido: ürünü (filtre (Yok, [1,2,3, Yok])) belirtmek için "buna ihtiyaç" olduğu yere harika bir örnek. Umarım bir gün dahil edilir.
the911s

13
Guido da sevmeyen adam değil reducemi?
Chris Martin

3
Evet - ve azaltma artık Python 3'te yerleşik değil. IMO, standart (veya 3. taraf) bir kitaplık yapıldığında global yerleşiklere eklenen olası her liste operatörüne ihtiyacımız yok. Ne kadar fazla yerleşime sahip olursanız, yerel değişken adları olarak daha yaygın kelimeler sınır dışı olur.
ojrac

7
Bu nugget'ı Guido'nun reduce () ile ilgili blog yayınında buldum . "Zaten toplam () var; Ürün () için mutlu bir şekilde reduce () ticareti yapardım . " product()Standart kütüphaneye dahil olmak için dilekçe vermek isteyen varsa , bu soruya ilişkin görüşlerin sayısı davanın ortaya çıkmasına yardımcı olabilir.
Patrick McElhaney

1
@PatrickMcElhaney Görünüşe göre python3 zaten indirgeme yerleşikinden kurtuldu. Ürünün şansını kaçırdığını düşünüyorum. ;)
ojrac


39

prod()İstediğini yapan bir numpy var.


3
not: Python uzunluğunu (keyfi tamsayılar) desteklemez, bu nedenle np.prod(range(1,13))12'ye eşit doğru cevabı verir! ama np.prod(range(1,14))değil.
Jason S

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

1
math.prod()Fonksiyon Bu cevap eskimiş yapacaktır.
Benoît P

Bunu basit bir tek katmanlı yapmak istediğinizde hala matematik almak zorunda sıkıcı. Reduce () ve Guido tarafından reddedilen ürünü () özledim.
RCross

25
Numeric.product 

(veya

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

)


Bir modül veya kütüphaneden yükleyebileceği bir fonksiyon istiyor, fonksiyonun kendisini yazmıyor.
Jeremy L

2
Ama eğer biri yoksa, muhtemelen hala işlevi istiyor.
DNS,

1
Doğru, ama var olmadığını bilmek gerekiyor, çünkü bu onun ana sorusu.
Jeremy L

2
Ayrıca varsayılan 1 değerini azaltmanız gerekir, aksi takdirde null durumunda başarısız olur. Boş bir dizinin ürünü 1 olarak tanımlanır.
Aaron Robson

3
@CraigMcQueen Numeric, numpy'nin öncülerinden biridir.
tacaswell

22

Bunu kullan

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

Yerleşik bir prodişlev olmadığından.


6
azaltmak gerçekten bir
antipattern

1
Kullanabileceği mevcut bir işlevin var olup olmadığını bilmek istiyordu.
Jeremy L

Ve bu cevap bir tane olmadığını açıklıyor.
EBGreen

5
@zweiterlinde: Yeni başlayanlar için, olası sorunlara yol açın. Bu durumda, kullanmak lambda a,b: a*bsorun değil. Ancak azaltma iyi bir genelleme yapmaz ve istismar edilir. Yeni başlayanların öğrenmemesini tercih ederim.
S.Lott

@ S.Lott Hiç yeni başlayanların kullanımı azalttığını görmedim, daha az diğer fonksiyonel esque yapıları. Heck, "ara" programcılar bile liste kavrayışının ötesinde pek bir şey bilmiyorlar.
Mateen Ulhaq


2

Belki bir "yerleşik" değil, ama yerleşik olduğunu düşünüyorum. neyse sadece numpy kullan

import numpy 
prod_sum = numpy.prod(some_list)

Bu tehlikeli bir şekilde "makinemde çalışıyor" ifadesine yakın! Numpy, güzel olsa da, kesin olarak bir yerleşik değildir .
RCross
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.