【问题标题】:Multiply all items in a list in Python [duplicate]在Python中将列表中的所有项目相乘[重复]
【发布时间】:2016-05-12 10:36:14
【问题描述】:

如何将列表中的项目相乘?

例如:

num_list = [1,2,3,4,5]

def multiplyListItems(l):
   # some code here...

预期的计算和返回值为1 x 2 x 3 x 4 x 5 = 120

【问题讨论】:

  • 我尝试使用 while 循环,但无法找出正确的逻辑。

标签: python list multiplication


【解决方案1】:

一种方法是使用reduce:

>>> num_list = [1,2,3,4,5]
>>> reduce(lambda x, y: x*y, num_list)
120

【讨论】:

  • 请注意,对于 python 3,您必须 'from itertools import reduce'
  • 我更喜欢从 operatore 导入 mul 而不是 lambda,正如 @sparkandshine 建议的那样
【解决方案2】:

使用functools.reduce,它更快(见下文)并且与 Python 3 更向前兼容。

import operator
import functools

num_list = [1,2,3,4,5]
accum_value = functools.reduce(operator.mul, num_list)

print(accum_value)
# Output
120

测量 3 种不同方式的执行时间,

# Way 1: reduce
$ python -m timeit "reduce(lambda x, y: x*y, [1,2,3,4,5])"
1000000 loops, best of 3: 0.727 usec per loop

# Way 2: np.multiply.reduce
$ python -m timeit -s "import numpy as np" "np.multiply.reduce([1,2,3,4,5])"
100000 loops, best of 3: 6.71 usec per loop

# Way 3: functools.reduce
$ python -m timeit -s "import operator, functools" "functools.reduce(operator.mul, [1,2,3,4,5])"
1000000 loops, best of 3: 0.421 usec per loop

对于更大的列表,最好使用@MikeMüller 提到的np.multiply.reduce

$ python -m timeit "reduce(lambda x, y: x*y, range(1, int(1e5)))"
10 loops, best of 3: 3.01 sec per loop

$ python -m timeit -s "import numpy as np" "np.multiply.reduce(range(1, int(1e5)))"
100 loops, best of 3: 11.2 msec per loop

$ python -m timeit -s "import operator, functools" "functools.reduce(operator.mul, range(1, int(1e5)))"
10 loops, best of 3: 2.98 sec per loop

【讨论】:

  • 谢谢,可以了
【解决方案3】:

一个 NumPy 解决方案:

>>> import numpy as np
>>> np.multiply.reduce(num_list)
120

更大列表的运行时间:

In [303]:
from operator import mul
from functools import reduce
import numpy as np
​
a = list(range(1, int(1e5)))

In [304]
%timeit np.multiply.reduce(a)
100 loops, best of 3: 8.25 ms per loop

In [305]:
%timeit reduce(lambda x, y: x*y, a)
1 loops, best of 3: 5.04 s per loop

In [306]:
%timeit reduce(mul, a)
1 loops, best of 3: 5.37 s per loop

NumPy 主要在 C 中实现。因此,它通常比在 Python 列表上编写循环快一到两个数量级。这适用于更大的数组。如果数组很小并且经常从 Python 中使用,那么事情可能会比使用纯 Python 慢。这是因为 Python 对象和 C 数据类型之间的开销转换。事实上,编写 Python for 循环来迭代 NumPy 数组是一种反模式。

在这里,与增益相比,包含五个数字的列表会导致相当大的开销 来自更快的数字。

【讨论】:

  • 我测量了 3 种不同方式的执行时间(结果请参考我的分析器),表明 np.multiply.reduce 比其他方式慢得多。
  • 尝试更大的列表。请参阅我的更新答案。
  • @MikiMüller,太好了,你能解释一下吗?
  • @sparkandshine 添加了一些解释。