Hàm nào giống như sum () nhưng để nhân? sản phẩm ()?


206

sum()Hàm Python trả về tổng số trong một lần lặp.

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

Tôi đang tìm kiếm chức năng trả về sản phẩm thay thế.

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

Tôi khá chắc chắn rằng một chức năng như vậy tồn tại, nhưng tôi không thể tìm thấy nó.

Câu trả lời:


71

Cập nhật:

Trong Python 3.8, hàm prod đã được thêm vào mô đun toán học . Xem: math.prod () .

Thông tin cũ hơn: Python 3.7 và trước đó

Hàm bạn đang tìm kiếm sẽ được gọi là prod () hoặc sản phẩm () nhưng Python không có chức năng đó. Vì vậy, bạn cần phải viết của riêng bạn (đó là dễ dàng).

Phát âm trên prod ()

Vâng đúng vậy. Guido đã từ chối ý tưởng cho hàm prod () tích hợp vì ông nghĩ rằng nó hiếm khi cần thiết.

Thay thế bằng giảm ()

Như bạn đã đề xuất, không khó để tự tạo bằng cách sử dụng less ()oper.mul () :

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

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

Lưu ý, trong Python 3, hàm less () đã được chuyển sang mô đun funcools .

Trường hợp cụ thể: Yếu tố

Là một lưu ý phụ, trường hợp sử dụng động lực chính cho prod () là để tính các giai thừa. Chúng tôi đã có hỗ trợ cho điều đó trong mô-đun toán học :

>>> import math

>>> math.factorial(10)
3628800

Thay thế bằng logarit

Nếu dữ liệu của bạn bao gồm các số float, bạn có thể tính toán một sản phẩm bằng sum () với số mũ và logarit:

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

Lưu ý, việc sử dụng log () yêu cầu tất cả các đầu vào là dương.


Bạn có thể muốn thêm rằng các số float trong ví dụ trước cần phải tích cực . Mặt khác, bạn có thể phải sử dụng cmath, nhưng ngay cả sau đó nó sẽ không thực sự hoạt động trong mọi trường hợp.
Veky

212

Trên thực tế, Guido đã phủ quyết ý tưởng: http://bugs.python.org/su1093

Nhưng, như đã lưu ý trong vấn đề đó, bạn có thể thực hiện một cách khá dễ dàng:

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

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

4
Dưới đây là một ví dụ tuyệt vời về nơi có "nhu cầu này", để trích dẫn Guido: sản phẩm (bộ lọc (Không có, [1,2,3, Không có])). Hy vọng nó sẽ được đưa vào một ngày nào đó.
the911s

13
Không phải Guido cũng là người không thích reducesao?
Chris Martin

3
Đúng - và giảm thậm chí không còn là một nội dung trong Python 3. IMO, chúng tôi không cần mọi toán tử danh sách có thể được thêm vào các nội dung toàn cầu khi thư viện (hoặc bên thứ 3) chuẩn sẽ làm. Bạn càng có nhiều nội dung, các từ phổ biến trở thành giới hạn dưới dạng tên biến cục bộ.
ojrac

7
Chỉ cần tìm thấy nugget này trong bài đăng trên blog của Guido về less () . "Chúng tôi đã có sum (); Tôi rất vui khi giao dịch giảm () cho sản phẩm () ..." . Nếu bất cứ ai muốn kiến ​​nghị bao gồm product()trong thư viện tiêu chuẩn, số lượt xem về câu hỏi này có thể giúp đưa ra vụ việc.
Patrick McElhaney

1
@PatrickMcElhaney Nghe có vẻ như python3 đã thoát khỏi phần dựng sẵn. Tôi nghĩ rằng sản phẩm đã bỏ lỡ cơ hội của nó. ;)
ojrac

41

Không có cái nào được tích hợp sẵn, nhưng thật đơn giản để tự cuộn, như đã trình bày ở đây :

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

Xem câu trả lời cho câu hỏi này:

Mô-đun Python nào phù hợp để thao tác dữ liệu trong danh sách?


8
Nếu sử dụng Python 3 sử dụng functools.reducethay vì reduce.
Steven Rumbalski

1
Để có thêm nhiều trò vui nhộn:prod = functools.partial(functools.reduce, operator.mul)
bukzor

39

Có một prod()điều khó hiểu là những gì bạn yêu cầu.


3
lưu ý: không hỗ trợ Python dài (số nguyên chính xác tùy ý) vì vậy hãy np.prod(range(1,13))đưa ra câu trả lời đúng bằng 12! nhưng np.prod(range(1,14))không.
Jason S

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

1
Các math.prod()chức năng sẽ làm cho câu trả lời này trở nên lỗi thời.
Benoît P

Vẫn còn tẻ nhạt khi phải nhập toán khi bạn muốn làm điều này trong một lớp lót đơn giản. Tôi nhớ giảm () và sản phẩm bị từ chối Guido ().
RCross

25
Numeric.product 

( hoặc là

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

)


Anh ta muốn một chức năng anh ta có thể tải từ một mô-đun hoặc thư viện, không phải tự viết chức năng đó.
Jeremy L

2
Nhưng nếu không có, có lẽ anh ta vẫn muốn chức năng này.
DNS

1
Phải, nhưng anh ta cần biết một người không tồn tại, vì đó là câu hỏi chính của anh ta.
Jeremy L

2
Bạn cũng phải giảm giá trị mặc định là 1 nếu không nó sẽ thất bại trong trường hợp null. Sản phẩm của một chuỗi trống được định nghĩa là 1.
Aaron Robson

3
@CraigMcQueen Numeric là (một trong) tiền thân của numpy.
tacaswell

22

Dùng cái này

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

Vì không có prodchức năng tích hợp.


6
bạn phải nghĩ giảm thực sự là một
antipotype

1
Anh ta muốn biết nếu một chức năng hiện có tồn tại mà anh ta có thể sử dụng.
Jeremy L

Và câu trả lời này giải thích rằng không có.
EBGreen

5
@zweiterlinde: Dành cho người mới bắt đầu, giảm dẫn đến các vấn đề. Trong trường hợp này, sử dụng lambda a,b: a*b, nó không phải là một vấn đề. Nhưng giảm không khái quát tốt, và bị lạm dụng. Tôi thích người mới bắt đầu không học nó.
S.Lott

@ S.Lott Tôi chưa bao giờ thấy bất kỳ người mới bắt đầu sử dụng giảm, ít hơn bất kỳ cấu trúc esque chức năng khác. Heck, ngay cả các lập trình viên "trung gian" thường không biết nhiều ngoài việc hiểu danh sách.
Mateen Ulhaq


2

Có lẽ không phải là "dựng sẵn", nhưng tôi coi đó là nội dung. dù sao chỉ cần sử dụng numpy

import numpy 
prod_sum = numpy.prod(some_list)

Điều đó rất nguy hiểm gần với một tuyên bố "hoạt động trên máy của tôi"! Numpy, đáng yêu mặc dù nó là, không rõ ràng không phải là một dựng sẵn.
RCross
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.