### Question :

I need to write a function that takes

a **list** of numbers and **multiplies** them together. Example:

`[1,2,3,4,5,6]`

will give me `1*2*3*4*5*6`

. I could really use your help.

##
Answer #1:

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 `pip install six`

, then:

```
>>> from six.moves import reduce
>>> reduce(lambda x, y: x*y, [1,2,3,4,5,6])
720
```

##
Answer #2:

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

##
Answer #3:

I would use the `numpy.prod`

to perform the task. See below.

```
import numpy as np
mylist = [1, 2, 3, 4, 5, 6]
result = np.prod(np.array(mylist))
```

##
Answer #4:

If you want to avoid importing anything and avoid more complex areas of Python, you can use a simple for loop

```
product = 1 # Don't use 0 here, otherwise, you'll get zero
# because anything times zero will be zero.
list = [1, 2, 3]
for x in list:
product *= x
```

##
Answer #5:

Starting `Python 3.8`

, a `.prod`

function has been included to the `math`

module in the standard library:

`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).

##
Answer #6:

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.

##
Answer #7:

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

##
Answer #8:

The simple way is:

```
import numpy as np
np.exp(np.log(your_array).sum())
```