2017-09-24 289 views
3

我有两个嵌套列表:Python的SUMPRODUCT

a = [[1,2,3],[2,4,2]] 
b = [[5,5,5],[1,1,1]] 

我想繁殖和SUMPRODUCT各组元素得到

c = [[30],[8]] 

= [[1*2+2*5+3*5],[2*1,4*1,2*1]]

这导致我试过了:

c = sum(x * y for x, y in zip(a, b)) 

但我得到“不能乘以类型'列表'的非int的序列”

是否有一个简单的列表理解方式来避免循环?

+0

而应该首先尝试将它与循环写,并添加一些'print's明白是怎么回事。当你理解它时,你可以用更简洁的方式重写它。 –

+0

嗯... 1 * 2 + 2 * 5 + 3 * 5 = 30是怎么回事?操作顺序说“乘,然后加”,所以它应该是2 + 10 + 15 = 27,对吗? – willnx

+0

看起来你正在尝试做矩阵乘法。如果是这样,你可能想在'numpy'中开始使用多维数组。 – Bill

回答

0

你可以用嵌套的列表理解来做,但它会很复杂。这是一次一步。

a = [[1,2,3],[2,4,2]] 
b = [[5,5,5],[1,1,1]] 
result1 = [[x*y for x, y in zip(r1, r2)] for r1, r2 in zip(a, b)] 
c = [[sum(r)] for r in result1] 

c 
[[30], [8]] 
+0

你的代码不赞同你的文本,它是一个嵌套的列表理解。 –

+0

已更正。谢谢@斯特凡。 – Bill

+0

好点@斯特凡。我无法弄清楚如何不嵌套! – Bill

0

numpy的解决方案

import numpy as np 

c = map(lambda x: sum(np.prod((np.array(x)), axis=0)), zip(a,b)) 

[30, 8] 

如果您需要制作[[30], [8]]然后

c = map(lambda x: [sum(np.prod((np.array(x)), axis=0))], zip(a,b)) 
+1

这不是理想的结果。如果是的话,你也可以做'(np.array(a)* b)。sum(1).tolist()',不是? (我不确定,我是一个numpy noob) –

+0

为了得到确切的结果,你将不得不重塑阵列。 '(np.array(a)* np.array(b))。sum(1).reshape((2,1))。tolist()' – Bill

+0

或者你可以在括号内加上'sum'函数会产生'[[30],[8]]' –

1

没有numpy的

与列表理解一个解决方案,也许会这样:

a = [[1,2,3],[2,4,2]] 
b = [[5,5,5],[1,1,1]] 

c = [[sum(map(lambda m: reduce(lambda h,i: h * i, m), n))] for n in [zip(x, y) for x, y in zip(a, b)]] 

并告诉我:

[[30], [8]] 

另一个更干净的解决方案是一个简单的for循环

a = [[1,2,3],[2,4,2]] 
b = [[5,5,5],[1,1,1]] 

c = [] 

for x, y in zip(a, b): 
    temp = [] 
    for m, n in zip(x,y): 
     temp.append(m * n) 
    c.append([sum(temp)]) 

结果:

[[30], [8]] 

对不起,不读的变量名,我在这个c中推荐简单的for ASES

1

您可以实现dotproductitertools recipes

import operator 


def dotproduct(vec1, vec2): 
    return sum(map(operator.mul, vec1, vec2)) 

代码

a = [[1,2,3], [2,4,2]] 
b = [[5,5,5], [1,1,1]] 

[[dotproduct(x, y)] for x, y in zip(a, b)] 
# [[30], [8]]