2015-05-21 72 views
0

我想乘以列表的第一個列表的第一個數字1,第二個列表的第二個數字5,等等。例如,對於[[1,2,3],[4,5,6],[7,8,9]],我想要得到1 * 5 * 9。瞭解減少與列表的列表

雖然有很多方法可以做到這一點,我想知道如何減少與枚舉作用:

def test(m): 
    return reduce(lambda a, b: a[1][a[0]]*b[1][b[0]], enumerate(m)) 

print test([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) 

我認爲a在開始的時候是(0,[1,2,3]),所以a [1]是[1,2,3],a [0]是0,所以a [1] [a [0]]是1.

但是,我得到以下例外:

return reduce(lambda a, b: a[1][a[0]]*b[1][b[0]], enumerate(mat)) 
TypeError: 'int' object has no attribute '__getitem__' 

爲什麼是a整數?

+0

一點也不確定你想要做什麼 - 列舉一個列表會給你索引和值(如果你想用索引做些什麼)。否則不需要'枚舉'。所以我猜這有問題。所以從你的輸入 - 這是絕對不清楚你想要做什麼。如果您想在列表中添加多個項目,請清楚您的輸入和預期輸出。不幸的是,您的文章是一個問題和實驗的混合體 - 無法理解您正在嘗試做什麼! – gabhijit

回答

4

您的最終和中間值是簡單的整數。所以你應該從1開始,然後lambda將總是得到一個整數a,即迄今爲止的產品。而b將成爲下一個枚舉項目。因此,這裏是如何做到這一點:

>>> reduce(lambda a, b: a * b[1][b[0]], 
      enumerate([[1, 2, 3], [4, 5, 6], [7,8,9]]), 1) 
45 

Python 2裏仍然允許這,順便說一句:

>>> reduce(lambda a, (i, b): a * b[i], 
      enumerate([[1, 2, 3], [4, 5, 6], [7,8,9]]), 1) 
45 
+0

我想做的事(僅僅用於練習)更像是使用列表列表的方形矩陣的對角元素的產物,就像我在原始文章中所說的那樣。所以,我所追求的是特殊情況下的1 * 5 * 9。雖然有很多其他方法可以做到這一點(例如使用for循環),但我選擇使用枚舉來索引對角線元素,但仍堅持我沒有想到的行爲。 2元組的例子按我的預期工作:它產生5(= 1 * 5),它應該是一個整數。 – JustDoIt

+0

Ah darn,我誤解了。檢查我現在更新的答案的頂部。其餘的仍然有些有效,所以我現在就離開它。 –

+0

@JustDoIt現在我實際上改變了整個事情:-) –

1

那麼既然你想達到對角線號的最終值相乘這是怎麼Ø倒是做到這一點:

實施例:

def idiagonal(xs_of_ys): 
    for i, x in enumerate(xs_of_ys): 
     for j, y in enumerate(x): 
      if i == j: 
       yield y 


print reduce(lambda x, y: x * y, idiagonal(xs), 1) # prints 45 
+0

這不是我想要做的,我想爲特定的例子乘以1 * 5 * 9,正如我在原始文章中所說的那樣,我使用列舉選擇數字(第一個列表中的第一個數字,第二個列表中的第二個數字,等等) – JustDoIt

0

從你在其中一個評論中解釋了什麼 - 你試圖乘以一個矩陣的對角線元素,現在我明白你爲什麼要「枚舉」 - 這確實是正確的,因爲你想得到這個索引。所以下面的代碼會爲你做。

第一張地圖獲取列表中所有必需的元素,然後將其縮小到所需的值。注意:有幾個警告,枚舉給出了一個元組,所以你必須在地圖lambda中將它添加爲(x,y)。

a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 
reduce(lambda p,q: p*q, map(lambda (x,y): y[x], enumerate(a)), 1) 

reduce(lambda p,q: p*q, [y[x] for (x,y) in enumerate(a)], 1) 

編輯:增加了一個列表理解版本,而不是地圖 - 拉姆達。

請注意,列表理解版本與上述答案差不多快(只有10%左右),爲了便於閱讀,我會交易。

+0

我只是試着用@Stefan Pochman的答案來解答這個問題,正如預期的那樣,上面的答案約爲50%對於@Stefan Pochman的回答來說比較慢 - 這是直觀地預期的(列表在地圖上建立起來),但並不慢 - 我認爲。就我個人而言,我發現這比'x [1] [x [0]]'更可讀,但這是一個品味問題。 – gabhijit

0

儘管Stefan的答案在功能上是完美的,但我想指出......我們不是編譯器,你知道的。有沒有阻止我們寫的東西更具有可讀性,即使說明了什麼你正在嘗試做的沒有解釋一件事:

from collections import namedtuple 
Row = namedtuple('Row', ['num', 'columns']) 

m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 
reduce(lambda result, row: result * row.columns[row.num], 
     (Row(*data) for data in enumerate(m)), 1) 

望着減少功能,現在我們知道要積累上在列的項目數字=行號。如果這不拼寫對角線,我不知道是什麼:)