1

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

Community
  • 1
  • 1
undershock
  • 754
  • 1
  • 6
  • 26
  • 3
    Why the objection to `from functools import reduce`? – chepner Sep 02 '14 at 16:02
  • 1
    Also, what's wrong with a `for` loop? It's explicit, it's simple, it's Pythonic. – Joel Cornett Sep 02 '14 at 16:03
  • 3
    Using `functools.reduce(operator.mul, lst)` is pythonic in my book. So is importing that one module. – Martijn Pieters Sep 02 '14 at 16:03
  • @chepner - nothing in particular really. I assume moving it out of the namespace was to discourage use. – undershock Sep 02 '14 at 16:05
  • It was moved out of builtins because it didn't justify being a builtin, that doesn't mean it's not the right tool for this job. – roippi Sep 02 '14 at 16:07
  • 1
    @shipt: no, it was not seen as generally useful enough to be kept in the default namespace. Just like the `array` type is not in the default namespace. It is still *useful for specific tasks*. Otherwise it'd have been removed outright. – Martijn Pieters Sep 02 '14 at 16:08
  • @MartijnPieters - I see, thanks for clarifying. Guess I misunderstood _why_ it had been moved out of builtins – undershock Sep 02 '14 at 16:21
  • @JoelCornett - again, nothing. Just felt a bit more verbose. Particularly having to initialise the sum variable which for something this trivial I'd argue isn't all that pythonic. – undershock Sep 02 '14 at 16:22

1 Answers1

3

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)  
chepner
  • 497,756
  • 71
  • 530
  • 681
  • Note that in python3, the `reduce()` function has been removed from the global namespace, so you would need to import it by `from functools import reduce` – rhlobo Sep 02 '14 at 17:19
  • @rhlobo Which I have in the first example. I left out the implied `import functools, operator` from the example for `product`. – chepner Sep 02 '14 at 17:34
  • 1
    Sorry, I must be getting crazy – rhlobo Sep 03 '14 at 13:24