如何在 reduce 函数中使用 python 生成器?

How to use python generators in reduce function?

有人可以帮我理解这段代码的执行吗?

from functools import reduce

def foo():
    for i in range(10):
        yield i

gen = foo()

print (gen == 0, gen.__next__ == 0, gen.__next__ == 1, reduce(lambda a,b:a+b, gen))

我的问题如下:

如果有人能把生成器和reduce函数的功能映射出来,那将有很大帮助!谢谢!

如您所见,gen 是一个生成器; print 中的所有测试都是荒谬的(如果他们添加调用括号以获得 gen.__next__() 那么与 01 的比较将 return True 我想,但通过不调用它,可以保证 False).

至于reduce,那是在the docs。 reducer 函数的每次调用都使用先前调用的结果(内部存储在 reduce 函数的局部变量中,除非传递给 reducer 函数,否则不可见)作为第一个参数(在第一次调用时,这是可选的第三个参数 initializer,或者第一次调用是使用 gen 中的前两个元素执行的),下一个输入迭代结果为 b.

因此,如果实际上调用了 __next__(使用 gen 的前两个值),则第一次调用将使用 2 作为 a3 作为 b;下一次调用的结果 (5) 将是 ab 来自 gen (4) 的下一个值,生成 9,等等。步进它出前几步。你会看到:

  1. a = 2, b = 3 -> 5
  2. a = 5, b = 4 -> 9
  3. a = 9, b = 5 -> 14
  4. a = 14, b = 6 -> 20

等等;实际上,它只是使用 reduce 作为 sum 函数的 slow/ugly 形式。

关于你的第四个问题:生成器是懒惰的。当请求下一个值时,执行切换到生成器,当生成它时,生成器是 "hibernated" 直到请求下一个值。所以在这种情况下,是的,传递给 reducelambda 的每次调用都对应于 gen 的额外读取(第一次调用需要两次读取,因为它需要获得一个累加器值开始),但它完全是按需的;这里没有真正的并行性;当 gen 恢复时,要求它提供值的代码将暂停等待结果;当没有从中请求任何值时,gen 是 "frozen" 无限期(根本不是后台处理)。