简体   繁体   中英

Python how to reduce multiple lists?

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?

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)

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))

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.

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

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)

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]])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM