有人可以帮我理解这段代码的执行情况吗?
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))
我的问题如下:
如果有人能够确定发电机的功能和减少功能,那将有很大帮助!谢谢!
答案 0 :(得分:2)
如您所知,gen
是一个发电机; print
中的所有测试都是荒谬的(如果他们添加了调用parens来获取gen.__next__()
,那么与0
和1
的比较会返回True
我想但是,如果没有打电话,它可以保证False
)。
至于reduce
,the docs中的reduce
。 reducer函数的每次调用都使用先前调用的结果(存储在initializer
函数的本地内部,除非它被传递给reducer函数时不可见)作为第一个参数(在第一次调用时,这是可选的第三个参数gen
,或者第一个调用是使用b
中的前两个元素执行的,而下一个结果来自输入可迭代的__next__
}。
因此,如果gen
实际上已被调用(使用2
中的前两个值),则第一个调用会将a
用作3
和b
作为5
;下次调用的结果(a
)为b
,4
为gen(9
)的下一个值,生成a = 2, b = 3 -> 5
等。它出了头几个步骤。你会看到:
a = 5, b = 4 -> 9
a = 9, b = 5 -> 14
a = 14, b = 6 -> 20
reduce
等等;实际上,它只是使用sum
作为lambda
函数的缓慢/丑陋形式。
关于你的第四个问题:发电机是懒惰的。当请求下一个值时,执行切换到生成器,并且当它生成时,生成器被“休眠”"直到请求下一个值。所以在这种情况下,是的,传递给reduce
的{{1}}的每次调用都对应于gen
的额外读取(第一次调用的两次读取,因为它需要获取累加器值开始),但它完全按需;这里没有真正的并行性;当gen
恢复时,要求其输入值的代码暂停,等待结果;当没有请求它的值时,gen
被"冻结"无限期(根本不是后台处理)。