Reputation: 54541
I am able to use map
and sum
to achieve this functionality, but how to use reduce
?
There are 2 lists: a
, b
, they have same number of values. I want to calculate
a[0]*b[0]+a[1]*b[1]+...+a[n]*b[n]
The working version I wrote using map
is
value = sum(map(lambda (x,y): x*y, zip(a, b)))
How to use reduce
then? I wrote:
value = reduce(lambda (x,y): x[0]*y[0] + x[1]*y[1], zip(a, b)))
I got the error "TypeError: 'float' object is unsubscriptable
".
Can anyone shed some light on this?
Upvotes: 13
Views: 21226
Reputation: 2400
an update on the accepted answer (by @antonakos):
The ability to unpack tuple parameters was removed in Python 3.x
so the solution
value = reduce(lambda sum, (x, y): sum + x*y, zip(a, b), 0)
might give you a syntax error:
value = reduce(lambda sum, (x,y): sum + x*y, zip(a,b), 0)
^
SyntaxError: invalid syntax
To work on both Python 2.x and 3.x, You can manually unpack the tuple instead:
from functools import reduce
a = [1,2,3]
b = [1,4,8]
value = reduce(lambda sum, xy: sum + xy[0]+xy[1], zip(a,b), 0)
print("result:", value)
result: 19
Upvotes: 2
Reputation: 200
it looks like you want an inner product. use an inner product. https://docs.scipy.org/doc/numpy/reference/generated/numpy.inner.html
np.inner(a, b) = sum(a[:]*b[:])
Ordinary inner product for vectors:
a = np.array([1,2,3])
b = np.array([0,1,0])
np.inner(a, b)
output: 2
A multidimensional example:
a = np.arange(24).reshape((2,3,4))
b = np.arange(4)
np.inner(a, b)
output: array([[ 14, 38, 62],[ 86, 110, 134]])
Upvotes: 1
Reputation: 9256
Difficulties with reduce happen when you have incorrect map.
Let's take expression:
value = sum(map(lambda (x,y): x*y, zip(a, b)))
Map is transformation. We need it to convert tuples into simple flat values. In your case it will look like:
map(lambda x: x[0]*x[1], zip(a,b))
And then, if you want to express sum
via reduce
- it will look like:
reduce(lambda x,y: x + y, map)
So, here is example:
a = [1,2,3]
b = [4,5,6]
l = zip(a,b)
m = map(lambda x: x[0]*x[1], l)
r = reduce(lambda x,y: x + y, m)
Upvotes: 1
Reputation: 9186
A solution using reduce
and map
,
from operator import add,mul
a = [1,2,3]
b = [4,5,6]
print reduce(add,map(mul,a,b))
Upvotes: 8
Reputation: 53526
I would do it this way (I don't think you need lambda)...
sum(x*y for x, y in zip(a, b))
This also seems slightly more explicit. Zip AB, multiply them, and sum up the terms.
Upvotes: 7
Reputation: 8361
The first argument of the lambda function is the sum so far and the second argument is the next pair of elements:
value = reduce(lambda sum, (x, y): sum + x*y, zip(a, b), 0)
Upvotes: 8