含For In的Python生成器仅返回首个字符,为何异常?
问题原因与解决方法
核心问题:每次调用next()时都新建了生成器实例
你的代码里,列表推导式[next(gn()) for _ in range(10)]的问题在于:每一次循环都会执行gn()创建一个全新的生成器对象。
生成器是惰性执行的,每个新生成器启动后,会进入while True循环,再进入for char in ">><<"循环,取第一个字符">"后就暂停在yield处。所以每次next()都是取新生成器的第一个值,自然输出全是">>>>>>"。
第二个测试代码gn2()的问题完全一样:每次next(gn2())都新建实例,永远只取到生成器的第一个">"。
为什么换成print就正常?
如果把yield换成print,调用gn()时会直接执行整个函数逻辑:进入无限循环,不断遍历">><<"并打印字符。这时候函数是主动持续执行的,不存在生成器的暂停/惰性特性,也不需要反复调用next(),所以能正常输出循环序列。
正确写法
要实现循环取序列,必须先创建一个生成器实例,然后反复对这个实例调用next():
def gn(): while True: for char in ">><<": yield char # 先创建单个生成器实例 gen = gn() # 对同一个实例多次调用next print([next(gen) for _ in range(10)])
执行后会输出:['>', '>', '<', '<', '>', '>', '<', '<', '>', '>'],也就是循环的">><<"序列。
如果要得到">><<><"的循环,只需修改for循环的遍历对象为">><<><"即可:
def gn(): while True: for char in ">><<><": yield char gen = gn() print([next(gen) for _ in range(10)])
输出:['>', '>', '<', '<', '>', '<', '>', '>', '<', '<']
内容的提问来源于stack exchange,提问作者Chris Rudd
相关产品推荐
相关产品推荐

