Python递归扁平化嵌套列表生成器失效问题排查
问题分析:Python递归生成器实现扁平化函数返回空列表的原因
嘿,我来帮你拆解下这个问题——你的递归生成器之所以返回空列表,核心问题在于递归调用时没有产出子生成器的结果。
先看你的原实现代码:
def flatten(toflatten): try: for element in toflatten: flatten(element) # 这里只创建了生成器,但没有迭代产出结果 except TypeError: yield toflatten
为什么会返回空列表?
生成器是惰性执行的:你调用flatten(element)只会创建一个生成器对象,不会自动执行里面的代码。如果不主动迭代这个生成器、把它的元素传递出来,那么子生成器里的yield语句根本不会触发,自然没有任何元素被产出到上层生成器中。
比如当处理子列表[4,5,6]时,你调用flatten([4,5,6]),但这个生成器没有被迭代,所以里面的循环和yield逻辑完全没运行,4、5、6这些元素根本不会被传递到外层生成器里。
修正方案
你需要把递归生成器的结果“传递”出来,有两种简洁的方式:
方式1:使用yield from(Python 3.3+ 支持,你的3.5版本完全可用)
yield from会自动迭代子生成器,并把它产出的所有元素传递到当前生成器中,是处理嵌套生成器的语法糖:
def flatten(toflatten): try: for element in toflatten: yield from flatten(element) except TypeError: yield toflatten
方式2:手动嵌套循环迭代子生成器
如果你需要兼容更早的Python版本,可以手动循环子生成器的每个元素并yield:
def flatten(toflatten): try: for element in toflatten: # 迭代递归生成器的每个元素,逐个产出 for item in flatten(element): yield item except TypeError: yield toflatten
测试验证
现在调用print(list(flatten([1,2,3,[4,5,6]]))),就能得到预期的输出:[1,2,3,4,5,6]了。
内容的提问来源于stack exchange,提问作者ChuckSchuldiner
相关产品推荐
相关产品推荐

