【问题标题】:What's the function like sum() but for multiplication? product()?sum() 之类的函数是什么,但用于乘法?产品()?
【发布时间】:2010-10-10 08:53:35
【问题描述】:

Python 的 sum() 函数返回可迭代对象中数字的总和。

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

我正在寻找返回产品的函数。

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

我很确定这样的功能存在,但我找不到。

【问题讨论】:

    标签: python product built-in pep


    【解决方案1】:

    实际上,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)
    

    【讨论】:

    • 这里有一个很好的例子来说明“需要这个”,引用 Guido 的话:product(filter(None, [1,2,3,None]))。希望有一天它会被包括在内。
    • Guido不也是那个不喜欢reduce的人吗?
    • 是的——并且 reduce 甚至不再是 Python 3 中的内置函数。IMO,当标准(或第 3 方)库可以执行时,我们不需要将所有可能的列表运算符添加到全局内置函数中.你拥有的内建函数越多,越常见的词成为局部变量名的禁区。
    • 刚刚在Guido's blog post about reduce() 中找到了这个金块。 “我们已经有了 sum();我很乐意用 reduce() 换取 product()...”。如果有人想请求在标准库中包含product(),那么这个问题的浏览量可能有助于证明这一点。
    • @PatrickMcElhaney 听起来 python3 已经摆脱了 reduce 内置函数。我认为产品错过了机会。 ;)
    【解决方案2】:

    更新:

    在 Python 3.8 中,prod 函数被添加到 math 模块中。请参阅:math.prod()

    旧信息:Python 3.7 及之前的版本

    您要查找的函数将称为 prod()product(),但 Python 没有该函数。所以,你需要自己写(这很容易)。

    prod() 上的声明

    是的,没错。 Guido rejected the idea 用于内置 prod() 函数,因为他认为它很少需要。

    reduce() 的替代方法

    正如您所建议的,使用reduce()operator.mul() 制作您自己的并不难:

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

    注意,在 Python 3 中,reduce() 函数已移至 functools module

    具体情况:阶乘

    附带说明,prod() 的主要激励用例是计算阶乘。我们已经在math module 中提供了支持:

    >>> import math
    
    >>> math.factorial(10)
    3628800
    

    对数替代

    如果您的数据由浮点数组成,您可以使用 sum() 与指数和对数计算乘积:

    >>> 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,但即便如此,它也并非在所有情况下都有效。
    【解决方案3】:

    在 numpy 中有一个 prod() 可以满足您的要求。

    【讨论】:

    • 注意:不支持 Python 长整数(任意精度整数),所以np.prod(range(1,13)) 给出的正确答案等于 12!但np.prod(range(1,14)) 没有。
    • @JasonS np.prod(arange(1,14, dtype='object'))?
    • math.prod() 函数将使这个答案过时。
    • 当您想在一个简单的单行中执行此操作时,必须导入数学仍然很乏味。我想念 reduce() 和 Guido 拒绝的 product()。
    【解决方案4】:

    没有内置的,但很容易自己滚动,如 here 所示:

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

    查看此问题的答案:

    Which Python module is suitable for data manipulation in a list?

    【讨论】:

    • 如果使用 Python 3,请使用 functools.reduce 而不是 reduce
    • 更多功能工具的乐趣:prod = functools.partial(functools.reduce, operator.mul)
    • 所以在 Python 3 中我需要 两个 导入来做一些如此基本的事情?!
    • @A.Donda 你需要在 Python 中使用导入来做更多基本的事情:平方根函数在数学中,线程在线程中等等。Python 不会避开命名空间,它是实际上是 Python 之禅的一个明确部分,它包含了它们。
    • @MarcelBesixdouze,是的,我同意命名空间是一个很棒的主意。但是恕我直言,在具有本地列表的语言中,将一堆数字相乘应该是内置的。而且我认为它比平方根和线程更基本。特别是后者足够复杂,需要一个模块。
    【解决方案5】:
    Numeric.product 
    

    (或

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

    )

    【讨论】:

    • 他想要一个可以从模块或库中加载的函数,而不是自己编写函数。
    • 但如果没有,他可能还想要这个功能。
    • 对,但他需要知道一个不存在,因为这是他的主要问题。
    • 你还必须给 reduce 一个默认值 1 否则它会在 null 情况下失败。空序列的乘积定义为 1。
    • @CraigMcQueen Numeric 是 numpy 的前身(之一)。
    【解决方案6】:

    使用这个

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

    由于没有内置的prod 函数。

    【讨论】:

    • 你一定认为reduce真的是一个反模式:)
    • 他想知道是否存在他可以使用的现有功能。
    • 这个答案说明没有。
    • @zweiterlinde:对于初学者来说,减少会导致问题。在这种情况下,使用lambda a,b: a*b,这不是问题。但是 reduce 不能很好地概括,并且被滥用。我更喜欢初学者而不是学习它。
    • @S.Lott 我从未见过任何初学者使用 reduce,更不用说任何其他函数式结构了。哎呀,即使是“中级”程序员通常也不懂列表理解。
    【解决方案7】:

    也许不是“内置”,但我认为它是内置的。无论如何,只需使用 numpy

    import numpy 
    prod_sum = numpy.prod(some_list)
    

    【讨论】:

    • 这与“在我的机器上工作”声明非常接近! Numpy,虽然很可爱,但明确不是内置的。
    【解决方案8】:

    我更喜欢上面使用functools.reduce()answer 使用numpy.prod() 的答案ab,但这里还有另一个使用itertools.accumulate() 的解决方案:

    import itertools
    import operator
    prod = list(itertools.accumulate((3, 4, 5), operator.mul))[-1]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-20
      • 1970-01-01
      相关资源
      最近更新 更多