Skip to main content
 首页 » 编程设计

python之reduce 方法的不同行为

2025年05月04日17lvdongjie

我有一个数字列表。我想计算列表某些子集的按位 和 。我使用了 reduce 方法。我认为这两种方法应该产生相同的结果。

table = [5, 10, 2, 6, 7, 18, 19, 1, 4, 9, 17, 8, 16, 0, 15, 11, 12, 13, 3, 14] 
l = [0,1,2,3] 
print reduce (lambda x,y:table[x]&table[y] , l )  
print reduce (lambda x,y:x&y , [ table[x] for x in l ] ) 

但经过大量调试后,我发现它们没有。我不明白背后的原因。

请您参考如下方法:

您误解了 reduce() 的作用。它使用 上次调用的结果 和列表中的下一个值调用 lambda。如果没有先前的值,则使用列表的第一个元素。

因此,x 每次都会成为之前的结果,第一次除外。它不会是您的列表推导式中的table[x],当不使用列表推导式时,它也不会是列表中的值。

对于您的第一个 reduce() 调用,会发生这种情况:

  • x 设置为 0,y 设置为 1。 table[0] & table[1] 计算得到5 & 10,结果为0。

  • x 因此设置为 0(先前的结果)并且 y 设置为 l 中的下一个值,所以 2。 table[0] & table[2] 被计算,使 5 & 2,结果又是 0。

  • x 因此设置为 0(先前的结果)并且 y 设置为 l 中的下一个值,所以 3。 table[0] & table[3] 被计算,使得 5 & 6,结果现在是 4。

您的第二个 reduce() 调用直接从 table 中获取值,因此您现在使用 [5, 10, 2, 6]作为输入,减少时不再引用 table:

  • x 设置为 5,y 设置为 10。 5 & 10 生成 0

  • x 因此设置为 0(先前的结果)并且 y 设置为列表中的下一个值,因此2。 0 & 2 被计算,结果又是 0。

  • x 因此设置为 0(先前的结果)并且 y 设置为列表中的下一个值,因此6。 0 & 6 被计算,结果又是 0。

区别在于您误解了选择的 table[x] 值。

因为 reduce() 每次都将调用应用于之前的结果,您应该真正将其视为一组链式调用。您的第一个 reduce() 可以写成:

table[table[table[0] & table[1]] & table[2]] & table[3] 

当您的第二个 reduce() 有效计算时:

((table[0] & table[1]) & table[2]) & table[3]