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
?

- 62,466
- 11
- 102
- 153

- 2,755
- 2
- 13
- 3
15 Answers
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
-
You don't import operator, so this solution is a bit more compact. I wonder which is faster. – jheld Jul 31 '14 at 22:07
-
33@jheld: I timed product-ing the numbers from 1 to 100. In both python2 and 3, `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. – whereswalden Nov 01 '14 at 18:49
-
@whereswalden Any idea as to why? – wordsforthewise Nov 09 '15 at 18:56
-
4@wordsforthewise probably it's that going through an extra function (lambda) adds overhead, whereas `operator.mul` goes straight to C. – whereswalden Nov 09 '15 at 20:32
-
4I really wouldn't call .009 an order of magnitude lower than .02. It's just about half. – jlh Apr 11 '18 at 21:28
-
8As of Python 3.8, it can be simply done with `math.prod([1,2,3,4,5,6])`. (requires import of-course) – Tomerikoo Jan 26 '20 at 23:51
-
1You don't need to install `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. – Alan Feb 28 '20 at 19:45
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+.
-
32Note that in python3, the `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`. – Eugene Yarmash Nov 01 '13 at 17:10
-
2The '1' as the third argument is unnecessary here, what's a case where it would be needed? – wordsforthewise Nov 09 '15 at 18:59
-
7@wordsforthewise without the third argument, it throws a TypeError exception if you pass it an empty sequence – Francisco Jul 11 '16 at 03:41
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))

- 18,379
- 16
- 47
- 61

- 1,394
- 1
- 9
- 6
-
20Convenient if you're already using Numpy. You probably don't even need to cast it as a list first, this should work for most cases `result = np.prod(mylist)` – Nick Jun 09 '16 at 23:47
-
6Two things to watch out for: **1)** It might overflow, especially if using the default `numpy.int32` as above **2)** For small lists this will be significantly slower, since NumPy needs to allocate an array (relevant if repeated often) – Disenchanted Nov 28 '17 at 10:09
-
2
-
It is not a good choice. It can overflow and it is slower. try `reduce`. – Peyman Jan 31 '20 at 12:58
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

- 4,379
- 1
- 27
- 34
-
10Minor note: Slices in Python are very easy, and since we're only dealing with primitives here, you can avoid the minor kludge of starting with 1 by starting with list[0] and iterating over list[1:]. Though getting comfortable with the more functional 'reduce' answers here is valuable in the long term as it's also useful in other circumstances. – kungphu Oct 26 '13 at 15:35
-
5@kungphu The empty product is usually defined as 1, your solution would throw an IndexError exception instead if you pass it an empty sequence – Francisco Jul 11 '16 at 03:44
-
@Francisco Granted, but this function probably _should_ throw some flavor of exception in that case, since an empty sequence would be invalid input for this function. In fact, this function is not meaningful for any sequence with less than two values; if you pass a sequence with one value and multiply it by 1, you've essentially added a value that wasn't there, which I'd say amounts to unexpected behavior. – kungphu Jul 11 '16 at 05:21
-
3@kungphu, the behaviour for this answer is correct, i.e. passing a list of length 1 returns the value, and passing a list of length 0 returns 1. It's in the same line of thinking that gives sum([]) as 0 or sum([3]) as 3. See: https://en.wikipedia.org/wiki/Empty_product – emorris Aug 22 '16 at 13:48
-
1I see your point regarding mathematical functions. However, in a practical development situation, I would call it a very rare situation where a function that's explicitly intended to operate on input _should_ return a value given what amounts to no input or invalid input. I suppose it depends on the goal of the exercise: If it's just to replicate the standard library, OK, perhaps it teaches people something about how the (or a) language is or can be implemented. Otherwise I'd say it misses out on a good opportunity to provide a lesson on valid and invalid arguments. – kungphu Aug 23 '16 at 02:54
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).

- 54,987
- 21
- 291
- 190
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.

- 1,048,767
- 296
- 4,058
- 3,343

- 565
- 6
- 16
-
You could add the [eval way](https://stackoverflow.com/a/39404394/281545) just out of curiosity – Mr_and_Mrs_D Mar 27 '18 at 10:55
-
2I suspect that `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. – Martijn Pieters Jan 04 '19 at 11:52
-
3Also, the numpy version has to first convert the numbers to a numpy array; you'd normally already have made that conversion, to include that in the timings is not really fair. With the list converted to a numpy array once, the `np.prod()` option starts becomes fastest at 100 elements or more. – Martijn Pieters Jan 04 '19 at 11:59
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!)

- 7,717
- 5
- 38
- 70

- 107
- 1
- 1
-
8Why not `for i in n:`, then `total *= i`? would not it be much simpler? – Munim Munna Jul 22 '18 at 21:42
The simple way is:
import numpy as np
np.exp(np.log(your_array).sum())
-
12
-
a) taking logs is expensive. b) ill behaved for for zero and negative values.. could be fixed by using abs, and counting the negatives, and bailing if there is a zero either by checking in advance or by the exception. regardless, it's expensive – ShpielMeister Oct 28 '21 at 05:04
nums = str(tuple([1,2,3]))
mul_nums = nums.replace(',','*')
print(eval(mul_nums))

- 73
- 1
- 1
-
5
-
3I chime in and try to explain the code: I personally like this code not much, since it uses eval, which interpretes the string as an argument or function (and is thus generally viewed as an unsafe thing to do, especially when handling input data). The line before that replaces every delimiting comma by a multiplicative `*`, such that eval will recognize this as a multiplicative. I wonder how the performance on this is, espcially in comparison to other solutions – dennlinger Aug 07 '17 at 19:50
-
3
-
[**Do not ever use `eval` (or `exec`) on data that could possibly come from outside the program in any form. It is a critical security risk. You allow the author of the data to run arbitrary code on your computer. It cannot easily be sandboxed, and proper sandboxing is harder than using a proper tool for the job.**](https://stackoverflow.com/questions/1832940/why-is-using-eval-a-bad-practice) – Karl Knechtel Feb 03 '23 at 17:12
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))

- 1,784
- 1
- 15
- 24
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.

- 346
- 2
- 7
-
1The `:=` operator was added in 3.8, and this works in 3.8 and up. However, this is needlessly cryptic. – Karl Knechtel Feb 03 '23 at 17:09
-
Thanks for the comment, however, my solution isn't aiming to be efficient or pretty, the only reason for it is being a one-liner. – Eilonlif Feb 04 '23 at 23:58
How about using recursion?
def multiply(lst):
if len(lst) > 1:
return multiply(lst[:-1])* lst[-1]
else:
return lst[0]

- 11
- 1
- 5
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))

- 302
- 4
- 13
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.

- 69
- 4