Search code examples
pythonpython-3.xpython-itertoolsiterable-unpacking

Unpacking iterable using map


Assuming I have two iterables of numbers of the same length

weights = range(0, 10)
values = range(0, 100, 10)

I need to count weighted sum. I know that it can be done with list comprehension

weighted_sum = sum(weight * value for weight, value in zip(weights, values))

I wonder if it can be done using map and operator.mul like

import operator

weighted_sum = sum(map(operator.mul, zip(weights, values)))

but this gives an error

Traceback (most recent call last):
  File "<input>", line 3, in <module>
TypeError: op_mul expected 2 arguments, got 1

so my question: is there any way of passing unpacked tuples to function using map?


Solution

  • map doesn't need the zip, just use

    weighted_sum = sum(map(operator.mul, weights, values))
    

    From map's Documentation

    If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel.

    Also mentioned in map's documentation is that instead you can use itertools.starmap instead of map for already zipped input.


    As Rahul hinted at, using numpy is always a good idea when dealing with numerics, actually something like

    import numpy as np
    
    np.asarray(weights) * values
    

    already should do the trick (though in contrast to map this requires the two arrays to be of same length, while map would map the shortest length).