Pythonic way of multiplying contents of list by one another in Python3
Question:
I note this question has already been asked here, but this mostly deals with python2:
How can I multiply all items in a list together with Python?
With the demise of reduce in python3 (see What is the problem with reduce()?), what is the best way to multiply numbers in an iterable together?
eg. [1,3,7,1,2]
-> 1*3*7*1*2
I’m using something like this at the moment
def foo(list)
sum = 1
for i in list:
sum *= i
return sum
I’d really like a one liner, without having to from functools import reduce
Something like: total = sum(b for a,b in items)
but for multiplication
Answers:
The major objection to reduce
seems to be abusing it with arbitrary reduction functions. If you stick with simple, pre-existing associative operators, there’s no reason not to use reduce
.
from functools import reduce
from operator import mul
x = reduce(mul, [1,3,7,1,2])
You can even go one step further and compose reduce
and mul
using functools.partial
.
product = functools.partial(functools.reduce, operator.mul)
x = product(b for a, b in items)
L_int = [1,3,7,1,2]
If you want to go without any import use as a ‘trick’ the builtin method eval().
Here your one-liner (which is by a way a perfect use of eval() for a good purpose):
total = eval('*'.join(str(i) for i in L_int]))
which gives printing value of total:
42
Don’t be bothered by the critics which consider eval() to be evil.
And if you accept some imports, but want to avoid reduce
your one-liner will be:
deque(acc(Lst,o_mul),maxlen=1).pop()
which packed in a function called mul
def mul(Lst):
from collections import deque
from itertools import accumulate as acc
from operator import mul as o_mul
return deque(acc(Lst, o_mul), maxlen=1).pop()
gives you the option to use:
total = mul(L_int)
I note this question has already been asked here, but this mostly deals with python2:
How can I multiply all items in a list together with Python?
With the demise of reduce in python3 (see What is the problem with reduce()?), what is the best way to multiply numbers in an iterable together?
eg. [1,3,7,1,2]
-> 1*3*7*1*2
I’m using something like this at the moment
def foo(list)
sum = 1
for i in list:
sum *= i
return sum
I’d really like a one liner, without having to from functools import reduce
Something like: total = sum(b for a,b in items)
but for multiplication
The major objection to reduce
seems to be abusing it with arbitrary reduction functions. If you stick with simple, pre-existing associative operators, there’s no reason not to use reduce
.
from functools import reduce
from operator import mul
x = reduce(mul, [1,3,7,1,2])
You can even go one step further and compose reduce
and mul
using functools.partial
.
product = functools.partial(functools.reduce, operator.mul)
x = product(b for a, b in items)
L_int = [1,3,7,1,2]
If you want to go without any import use as a ‘trick’ the builtin method eval().
Here your one-liner (which is by a way a perfect use of eval() for a good purpose):
total = eval('*'.join(str(i) for i in L_int]))
which gives printing value of total:
42
Don’t be bothered by the critics which consider eval() to be evil.
And if you accept some imports, but want to avoid reduce
your one-liner will be:
deque(acc(Lst,o_mul),maxlen=1).pop()
which packed in a function called mul
def mul(Lst):
from collections import deque
from itertools import accumulate as acc
from operator import mul as o_mul
return deque(acc(Lst, o_mul), maxlen=1).pop()
gives you the option to use:
total = mul(L_int)