2015-05-21 139 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) 

望着减少功能,现在我们知道要积累上在列的项目数字=行号。如果这不拼写对角线,我不知道是什么:)