ฟังก์ชันเช่น sum () แต่สำหรับการคูณคืออะไร ผลิตภัณฑ์ ()?


206

sum()ฟังก์ชันPython ส่งคืนผลรวมของตัวเลขใน iterable

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

ฉันกำลังมองหาฟังก์ชั่นที่ส่งคืนผลิตภัณฑ์แทน

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

ฉันค่อนข้างแน่ใจว่ามีฟังก์ชั่นดังกล่าวอยู่ แต่ฉันหามันไม่เจอ

คำตอบ:


71

ปรับปรุง:

ใน Python 3.8 ฟังก์ชันprodถูกเพิ่มเข้ากับโมดูลคณิตศาสตร์ ดู: math.prod ()

ข้อมูลเก่ากว่า: Python 3.7 และก่อนหน้า

ฟังก์ชันที่คุณต้องการจะเรียกว่าprod ()หรือproduct ()แต่ Python ไม่มีฟังก์ชันนั้น ดังนั้นคุณต้องเขียนของคุณเอง (ซึ่งง่าย)

การออกเสียงของ prod ()

ใช่มันเป็นสิ่งที่ถูก. กุยโด้ปฏิเสธความคิดสำหรับฟังก์ชัน prod () ในตัวเพราะเขาคิดว่าไม่ค่อยจำเป็น

ทางเลือกพร้อมลด ()

ตามที่คุณแนะนำก็ไม่ยากที่จะทำด้วยตัวเองโดยใช้ลด ()และoperator.mul () :

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

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

หมายเหตุในหลาม 3, ลด ()ฟังก์ชั่นถูกย้ายไปโมดูล functools

กรณีเฉพาะ: แฟคทอเรียล

ในฐานะที่เป็นบันทึกด้านข้าง, กรณีการใช้หลักที่สร้างแรงจูงใจสำหรับprod ()คือการคำนวณแฟคทอเรียล เราได้รับการสนับสนุนในโมดูลคณิตศาสตร์แล้ว :

>>> import math

>>> math.factorial(10)
3628800

ทางเลือกด้วยลอการิทึม

หากข้อมูลของคุณประกอบด้วยโฟลทคุณสามารถคำนวณผลิตภัณฑ์โดยใช้ผลรวม ()พร้อมเลขชี้กำลังและลอการิทึม:

>>> 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 ()ต้องการให้อินพุตทั้งหมดเป็นค่าบวก


คุณอาจต้องการที่จะเพิ่มที่ลอยในตัวอย่างที่ผ่านมาความต้องการที่จะเป็นบวก มิฉะนั้นคุณอาจต้องใช้ cmath แต่ก็ไม่สามารถใช้งานได้ในทุกกรณี
Veky

212

จริงๆแล้ว Guido คัดค้านความคิด: http://bugs.python.org/issue1093

แต่ดังที่กล่าวไว้ในปัญหานั้นคุณสามารถทำให้เป็นเรื่องง่าย

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

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

4
นี่คือตัวอย่างที่ยอดเยี่ยมของที่มี "ความต้องการสิ่งนี้" เพื่ออ้างถึง Guido: ผลิตภัณฑ์ (ตัวกรอง (ไม่มี, [1,2,3, ไม่มี]]) หวังว่ามันจะรวมอยู่ในสักวันหนึ่ง
the911s

13
กุยโด้ไม่ใช่คนที่ไม่ชอบreduceเหรอ?
Chris Martin

3
ใช่ - และการลดลงไม่ได้เป็นบิวอินใน Python 3 อีกต่อไป IMO เราไม่ต้องการตัวดำเนินการรายการที่เป็นไปได้ทั้งหมดที่เพิ่มเข้าไปใน buildins ส่วนกลางเมื่อไลบรารีมาตรฐาน (หรือบุคคลที่สาม) จะทำ ยิ่งคุณมีบิวด์อินมากเท่าใดคำทั่วไปก็ยิ่งมีขีด จำกัด มากขึ้นในฐานะชื่อตัวแปรโลคอล
ojrac

7
พบเพียงนักเก็ตนี้ในบล็อกโพสต์ของกุยเกี่ยวกับการลด () "เรามีผลรวม (); ฉันมีความสุขที่จะค้าลด () สำหรับผลิตภัณฑ์ () ..." หากใครต้องการยื่นคำร้องเพื่อรวมproduct()ไว้ในห้องสมุดมาตรฐานจำนวนการดูคำถามนี้อาจช่วยได้
Patrick McElhaney

1
@PatrickMcElhaney ดูเหมือนว่า python3 ได้กำจัดการลด builtin แล้ว ฉันคิดว่าผลิตภัณฑ์พลาดโอกาส ;)
ojrac

41

ไม่มีหนึ่งในตัว แต่มันง่ายที่จะม้วนของคุณเองดังที่แสดงไว้ที่นี่ :

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

ดูคำตอบสำหรับคำถามนี้:

โมดูล Python ใดที่เหมาะสำหรับการจัดการข้อมูลในรายการ?


8
ถ้าใช้งูหลาม 3 ใช้แทนfunctools.reduce reduce
Steven Rumbalski

1
เพื่อความสนุกในการใช้งานฟังก์ชั่นที่มากขึ้น:prod = functools.partial(functools.reduce, operator.mul)
bukzor

39

มีจำนวนมากที่ทำprod()ในสิ่งที่คุณต้องการ


3
หมายเหตุ: ไม่รองรับ Python long (จำนวนเต็มความแม่นยำตามอำเภอใจ) ดังนั้นnp.prod(range(1,13))ให้คำตอบที่ถูกต้องเท่ากับ 12! แต่np.prod(range(1,14))ไม่ได้
Jason S

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

1
math.prod()ฟังก์ชั่นที่จะทำให้คำตอบนี้ล้าสมัย
Benoît P

ยังคงน่าเบื่อที่จะต้องนำเข้าคณิตศาสตร์เมื่อคุณต้องการทำสิ่งนี้ในหนึ่งซับง่ายๆ ฉันคิดถึงการลด () และผลิตภัณฑ์ที่ปฏิเสธโดยกุยโด ()
RCross

25
Numeric.product 

( หรือ

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

)


เขาต้องการฟังก์ชั่นที่สามารถโหลดได้จากโมดูลหรือไลบรารีไม่ใช่เขียนฟังก์ชันเอง
Jeremy L

2
แต่ถ้าไม่มีสักอันเขาคงต้องการฟังก์ชั่น
DNS

1
ใช่ แต่เขาต้องการที่จะรู้ว่าไม่มีอยู่เนื่องจากเป็นคำถามหลักของเขา
Jeremy L

2
คุณต้องลดค่าเริ่มต้นที่ 1 มิฉะนั้นจะล้มเหลวในกรณีที่ไม่มีค่า ผลิตภัณฑ์ของลำดับที่ว่างเปล่าถูกกำหนดเป็น 1
Aaron Robson

3
@CraigMcQueen Numeric คือ (หนึ่งใน) รุ่นก่อนของ numpy
tacaswell

22

ใช้สิ่งนี้

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

เนื่องจากไม่มีprodฟังก์ชั่นในตัว


6
คุณต้องคิดลดจริงๆเป็น antipattern :)
zweiterlinde

1
เขาต้องการทราบว่ามีฟังก์ชั่นที่มีอยู่ที่เขาสามารถใช้ได้หรือไม่
Jeremy L

และคำตอบนี้อธิบายว่าไม่มีใคร
EBGreen

5
@zweiterlinde: สำหรับผู้เริ่มต้นให้ลดโอกาสในการเกิดปัญหา ในกรณีนี้การใช้lambda a,b: a*bมันไม่มีปัญหา แต่ลดไม่ได้พูดคุยกันได้ดีและถูกทารุณกรรม ฉันชอบผู้เริ่มต้นที่ไม่ได้เรียนรู้
S.Lott

@ S.Lott ฉันไม่เคยเห็นผู้เริ่มต้นใช้งานลดขนาดใด ๆ น้อย ๆ โครงสร้างหน้าที่การทำงานอื่น ๆ Heck แม้โปรแกรมเมอร์ "ขั้นกลาง" ก็มักไม่ค่อยรู้เรื่องรายการมากนัก
Mateen Ulhaq


2

อาจไม่ใช่ "builtin" แต่ฉันคิดว่ามันสร้างขึ้น ยังไงก็ใช้ numpy

import numpy 
prod_sum = numpy.prod(some_list)

นั่นเป็นอันตรายใกล้กับคำสั่ง "ทำงานบนเครื่องของฉัน"! Numpy, น่ารักแม้ว่ามันจะเป็น, ไม่แจ่มใสในตัว
RCross
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.