Given a list of numbers like [1,2,3,4,5,6]
, how can I write code to multiply them all together, i.e. compute 1*2*3*4*5*6
?
Python 3: use functools.reduce
:
>>> from functools import reduce
>>> reduce(lambda x, y: x*y, [1, 2, 3, 4, 5, 6])
720
Python 2: use reduce
:
>>> reduce(lambda x, y: x*y, [1, 2, 3, 4, 5, 6])
720
For compatible with 2 and 3 use Six (pip install six
), then:
>>> from six.moves import reduce
>>> reduce(lambda x, y: x*y, [1,2,3,4,5,6])
720
lambda
took an average of .02s/1000 repetitions, whereas operator.mul
took an average of .009s/1000 repetitions, making operator.mul
an order of magnitude faster. –
Horeb operator.mul
goes straight to C. –
Horeb math.prod([1,2,3,4,5,6])
. (requires import of-course) –
Langbehn six
to use the same syntax in Python 2.6 or 2.7 as in Python 3. You just need to use the same line from functools import reduce
as used in Python 3. –
Mckean You can use:
import operator
import functools
functools.reduce(operator.mul, [1,2,3,4,5,6], 1)
See reduce
and operator.mul
documentations for an explanation.
You need the import functools
line in Python 3+.
reduce()
function has been removed from the global namespace and placed in the functools
module. So in python3 you need to say from functools import reduce
. –
Clobber I would use the numpy.prod
to perform the task:
import numpy as np
mylist = [1, 2, 3, 4, 5, 6]
result = np.prod(np.array(mylist))
result = np.prod(mylist)
–
Shelburne numpy.int32
as above 2) For small lists this will be significantly slower, since NumPy needs to allocate an array (relevant if repeated often) –
Extricate np.prod(np.array(range(1,21)))
–
Jarboe reduce
. –
Rosina If you want to avoid importing anything and avoid more complex areas of Python, you can use a simple for loop:
nums = [1, 2, 3]
product = 1 # Don't use 0 here, otherwise, you'll get zero
# because anything times zero will be zero.
for num in nums:
product *= num
In Python 3.8
and up, the math
standard library module provides .prod
for this purpose:
math.prod(iterable, *, start=1)
The method returns the product of a start
value (default: 1) times an iterable of numbers:
import math
math.prod([1, 2, 3, 4, 5, 6])
# 720
If the iterable is empty, this will produce 1
(or the start
value, if provided).
Here's some performance measurements from my machine. Relevant in case this is performed for small inputs in a long-running loop:
import functools, operator, timeit
import numpy as np
def multiply_numpy(iterable):
return np.prod(np.array(iterable))
def multiply_functools(iterable):
return functools.reduce(operator.mul, iterable)
def multiply_manual(iterable):
prod = 1
for x in iterable:
prod *= x
return prod
sizesToTest = [5, 10, 100, 1000, 10000, 100000]
for size in sizesToTest:
data = [1] * size
timerNumpy = timeit.Timer(lambda: multiply_numpy(data))
timerFunctools = timeit.Timer(lambda: multiply_functools(data))
timerManual = timeit.Timer(lambda: multiply_manual(data))
repeats = int(5e6 / size)
resultNumpy = timerNumpy.timeit(repeats)
resultFunctools = timerFunctools.timeit(repeats)
resultManual = timerManual.timeit(repeats)
print(f'Input size: {size:>7d} Repeats: {repeats:>8d} Numpy: {resultNumpy:.3f}, Functools: {resultFunctools:.3f}, Manual: {resultManual:.3f}')
Results:
Input size: 5 Repeats: 1000000 Numpy: 4.670, Functools: 0.586, Manual: 0.459
Input size: 10 Repeats: 500000 Numpy: 2.443, Functools: 0.401, Manual: 0.321
Input size: 100 Repeats: 50000 Numpy: 0.505, Functools: 0.220, Manual: 0.197
Input size: 1000 Repeats: 5000 Numpy: 0.303, Functools: 0.207, Manual: 0.185
Input size: 10000 Repeats: 500 Numpy: 0.265, Functools: 0.194, Manual: 0.187
Input size: 100000 Repeats: 50 Numpy: 0.266, Functools: 0.198, Manual: 0.185
You can see that Numpy is quite a bit slower on smaller inputs, since it allocates an array before multiplication is performed. Also, watch out for the overflow in Numpy.
multiply_functools
and multiply_numpy
are weighed down by having to look up the np
,functools
and operator
globals, followed by attribute lookups. Would you mind switching to locals? _reduce=functools.reduce,
_mul=operator.mul` in the function signature then return _reduce(_mul, iterable)
in the body, etc. –
Norway np.prod()
option starts becomes fastest at 100 elements or more. –
Norway Numpy
has the prod()
function that returns the product of a list, or in this case since it's numpy, it's the product of an array over a given axis:
import numpy
a = [1,2,3,4,5,6]
b = numpy.prod(a)
...or else you can just import numpy.prod()
:
from numpy import prod
a = [1,2,3,4,5,6]
b = prod(a)
I personally like this for a function that multiplies all elements of a generic list together:
def multiply(n):
total = 1
for i in range(0, len(n)):
total *= n[i]
print total
It's compact, uses simple things (a variable and a for loop), and feels intuitive to me (it looks like how I'd think of the problem, just take one, multiply it, then multiply by the next, and so on!)
for i in n:
, then total *= i
? would not it be much simpler? –
Afflict The simple way is:
import numpy as np
np.exp(np.log(your_array).sum())
np.prod(your_Array)
–
Hoskins nums = str(tuple([1,2,3]))
mul_nums = nums.replace(',','*')
print(eval(mul_nums))
*
, such that eval will recognize this as a multiplicative. I wonder how the performance on this is, espcially in comparison to other solutions –
Normally Just wanna add a Python 3.8 One-liner answer:
def multiply(l):
return [b := 1, [b := b * a for a in l]][-1][-1]
print(multiply([2, 3, 8, 10]))
output:
480
explanation:
[b := 1,
is for defining a temporary variable...[b := b * a for a in l]
is for iterating over the list and multiplyingb
by every element...[-1][-1]
is because the final list is[b, [b * l[0], b * l[1], ..., b * l[-1]]]
. and so the element in the final position is the multiplication of all of the elements in the list.
:=
operator was added in 3.8, and this works in 3.8 and up. However, this is needlessly cryptic. –
Calley Found this question today but I noticed that it does not have the case where there are None
's in the list. So, the complete solution would be:
from functools import reduce
a = [None, 1, 2, 3, None, 4]
print(reduce(lambda x, y: (x if x else 1) * (y if y else 1), a))
In the case of addition, we have:
print(reduce(lambda x, y: (x if x else 0) + (y if y else 0), a))
How about using recursion?
def multiply(lst):
if len(lst) > 1:
return multiply(lst[:-1])* lst[-1]
else:
return lst[0]
One way you can use is math.prod()
For example:
import math
arr = [1, 2, 3, 4]
print(math.prod(arr))
Another way is numpy.prod()
This is another library to import
import numpy
arr = [1, 2, 3, 4]
print(numpy.prod(arr))
There are many good answers in this thread. If you want to do multiply a list in actual production I recommend using standard numpy or math packages.
If you are just looking for a quick and dirty solution and you don’t want to import anything you can do this:
l = [1,2,3,4,5,6]
def list_multiply(l):
return eval('*'.join(map(str,l)))
print(list_multiply(l))
#Output: 720
map(str,l)
converts each element in the list to a string. join
combines each element into one string separated by the *
symbol. eval
converts the string back into a function that can evaluated.
Warning: eval
is considered dangerous to use, especially if the program accepts user input because a user can potentially inject any function into the code and compromise your system.
© 2022 - 2024 — McMap. All rights reserved.