【问题标题】:Can I add an iterator to the reduce function?我可以在reduce函数中添加一个迭代器吗?
【发布时间】:2021-05-23 16:06:18
【问题描述】:

假设我有以下列表:A = [1,2,3,4],通过使用reduce 函数,找到元素的乘积,我可以做到

prodA = reduce(lambda x,y: x*y, A)

但是,如果我有另一个列表B=[9,8,7,6],我是否仍然可以使用reduce 函数来执行以下操作? (从上到下表示步骤)

9
(9+1)* 2
((9+1) *2)+8
(((9+1) *2)+8)*3
((((9+1) *2)+8)*3)+7
(((((9+1) *2)+8)*3)+7)*4
((((((9+1) *2)+8)*3)+7)*4)+6

我不太确定是否可以将列表B 的迭代器添加到reduce 函数中。我怎么能这样做?非常感谢!

【问题讨论】:

  • 您的示例有些奇怪:除了第二步添加 2 个术语外,这些步骤总是添加 1 个术语。这是一个错误吗?在9 之后似乎应该有一个步骤9+1?
  • @John Zwinck 感谢您的评论!是的,我刚刚修复了步骤:)
  • 您修复了我也想知道的括号,但是您仍然遇到这种奇怪的情况,即每一步中的术语数变为 1、3、4、5、6、7、8,...... ...为什么没有2个术语的步骤?

标签: python iterator reduce


【解决方案1】:

这看起来像是zip 的工作。具体来说,我们要将两个列表压缩在一起,然后我们会将归约函数表示为一个接受元组而不是简单整数的函数。

将我们的列表压缩在一起可以得到我们

>>> list(zip(A, B))
[(1, 9), (2, 8), (3, 7), (4, 6)]

您的函数在每一步都乘以 A 的元素,然后添加 B 的元素。因此,从1 开始(这是一个合理的默认值,因为我们要做的第一件事是相乘,所以1 将是第一个操作的标识),乘以元组的第一个元素并加上第二个元素。

reduce(lambda x, y: x * y[0] + y[1], zip(A, B), 1)

并且,根据您的输入,我们得到370,等于

((((9+1)*2)+8)*3+7)*4+6

【讨论】:

  • 非常感谢您的回答! 1代表x的初始值,对吧?
  • 正确。现在必须有一个初始值,因为我们的“累加器”(x 参数)将是单个值,而我们的元素(y 参数)是一个元组。由于它们看起来不再一样,我们需要一个明确的初始值。
  • 谢谢!!这真的很有帮助!
【解决方案2】:

您可以使用 zip 作为输入并使用 1 作为初始值:

from functools import reduce

A = [1,2,3,4]
B = [9,8,7,6]

r = reduce(lambda r,ab: r*ab[0]+ab[1],zip(A,B),1)
print(r) # 370

【讨论】:

  • 这是对变量名的超级混淆使用。您的 b 是一个元组,其中包含一个来自 A 的元素和一个来自 B 的元素!
  • 同意。我想,既然 Silvio 击败了我,没有人会接受这一点。现已修复。
猜你喜欢
  • 2021-05-23
  • 2010-11-05
  • 2019-03-18
  • 2015-06-15
  • 2012-06-04
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
  • 2018-11-27
相关资源
最近更新 更多