-2

I want to calculate the product sum of two lists using reduce() and a regular function.

The regular function to return the product is defined as:

    def func(maturity, weight):
        return maturity * weight

and the reduct function is like:

reduce(func, zip(terms, weights))

An error

"TypeError: can't multiply sequence by non-int of type 'tuple'" 

then appears. Is there any way to pass the regular function instead of lambda to calculate the product sum of the two lists?

Kallz
  • 3,244
  • 1
  • 20
  • 38
  • Can you please format your question to be more readable ? and provide example of how `terms` and `weights` looks like. – demonno Aug 28 '17 at 06:25
  • 1
    Looks like you want: `map(func, terms, weights)`... In this case - if your function isn't doing more than multiplying you can use a builtin for that, eg: `result = map(operator.mul, terms, weights)` – Jon Clements Aug 28 '17 at 06:28
  • Really sorry about the terrible format. I tried indenting the codes as the instruction says but the codes somehow didn't show in a neat way. – Siyu Zhuang Aug 28 '17 at 06:30
  • I get it! I misunderstood how reduce works. I should use map to get a list of products and them use reduce to sum them up. – Siyu Zhuang Aug 28 '17 at 06:34
  • @SiyuZhuang: Use `sum` to sum them up! – Mark Dickinson Aug 28 '17 at 06:41

2 Answers2

1

I think you're mis-understanding the use of reduce. What it does is apply an operation repeatedly on a vector to produce a scalar as the end result. What you want to do is apply the same function on separate elements which are not related. For that purpose, you need map:

out = map(func, terms, weights)

As Jon Clements noted, if your function is as simple as element-wise multiplication, you might consider using operator.mul instead:

import operator
out = map(operator.mul, terms, weights)
cs95
  • 379,657
  • 97
  • 704
  • 746
  • Unless `terms` or `weights` are both tuples, then the output from `map` will be a `list` in 2.7 anyway... so the `list` might well be redundant here. (And as per my comment on the question - if the only action is to multiple the two, then using `operator.mul` is not only fairly obvious what it does, but will probably be ever so slightly faster...) – Jon Clements Aug 28 '17 at 06:37
0

Error is because you are multiplying tuples, Both arguments in func are tuples which looks like this

('A', 1), ('B', 2)

If you take elements on index 1 it will work.

def func(maturity, weight):
    return maturity[1] * weight[1]


terms = ['A', 'B', 'C']
weights = [1, 2]

reduce(func, zip(terms, weights))

snippet

demonno
  • 524
  • 5
  • 14
  • It doesn't seem to work that way. There will be a TypeError: 'int' object has no attribute '__getitem__' – Siyu Zhuang Aug 28 '17 at 06:41
  • You can check snippet at the end of the answer, it works without exception in python2. You did not provide examples of `terms` and `weighs` values so I used my own guess. – demonno Aug 28 '17 at 06:47