Returning the product of a list

Without using lambda:

from operator import mul
# from functools import reduce # python3 compatibility
reduce(mul, list, 1)

it is better and faster. With python 2.7.5

from operator import mul
import numpy as np
import numexpr as ne
# from functools import reduce # python3 compatibility

a = range(1, 101)
%timeit reduce(lambda x, y: x * y, a)   # (1)
%timeit reduce(mul, a)                  # (2)
%timeit np.prod(a)                      # (3)
%timeit ne.evaluate("prod(a)")          # (4)

In the following configuration:

a = range(1, 101)  # A
a = np.array(a)    # B
a = np.arange(1, 1e4, dtype=int) #C
a = np.arange(1, 1e5, dtype=float) #D

Results with python 2.7.5


       |     1     |     2     |     3     |     4     |
-------+-----------+-----------+-----------+-----------+
 A       20.8 µs     13.3 µs     22.6 µs     39.6 µs     
 B        106 µs     95.3 µs     5.92 µs     26.1 µs
 C       4.34 ms     3.51 ms     16.7 µs     38.9 µs
 D       46.6 ms     38.5 ms      180 µs      216 µs

Result: np.prod is the fastest one, if you use np.array as data structure (18x for small array, 250x for large array)

with python 3.3.2:


       |     1     |     2     |     3     |     4     |
-------+-----------+-----------+-----------+-----------+
 A       23.6 µs     12.3 µs     68.6 µs     84.9 µs     
 B        133 µs      107 µs     7.42 µs     27.5 µs
 C       4.79 ms     3.74 ms     18.6 µs     40.9 µs
 D       48.4 ms     36.8 ms      187 µs      214 µs

Is python 3 slower?


from functools import reduce

a = [1, 2, 3]
reduce(lambda x, y: x * y, a, 1)

if you just have numbers in your list:

from numpy import prod
prod(list)

EDIT: as pointed out by @off99555 this does not work for large integer results in which case it returns a result of type numpy.int64 while Ian Clelland's solution based on operator.mul and reduce works for large integer results because it returns long.


Starting Python 3.8, a prod function has been included to the math module in the standard library:

math.prod(iterable, *, start=1)

which returns the product of a start value (default: 1) times an iterable of numbers:

import math

math.prod([2, 3, 4]) # 24

Note that if the iterable is empty, this will produce 1 (or the start value if provided).


Well if you really wanted to make it one line without importing anything you could do:

eval('*'.join(str(item) for item in list))

But don't.