2017-09-24 290 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]]