Python:递归生成器跳过值

Python: Recursive generator skips values

我试图在 python 中创建一个 递归 生成器函数, 使嵌套列表变平 。这是为了理解目的。这是代码

def flat(list_x):
    try:
        for element in list_x:
            yield flat(element).next()
    except TypeError:
        yield list_x 

所以我只得到嵌套列表第一个元素的扁平化列表。

l=[[1,2],[3,4]]
a=flat(l)
list(a)
[1,3]

编辑: 根据我的测试,这就是内部实际发生的情况。使用具有子列表 [1,2][3,4] 的测试列表 l=[[1,2],[3,4]。第一个循环遍历主列表的每个元素,然后对生成器的递归调用使其进入另一个 for 循环,此时对于第一个子列表它应该执行两个操作:

for 1 in [1,2]:
    yield flat(1).next()

此时将引发 TypeError 并产生值 1

for 2 in [1,2]:
    yield flat(2).next()

此时应该引发另一个 TypeError 异常并产生值 2 但它没有这样做,因此标题。我已经对此进行了广泛的测试,这正是行为,列表可以做得更长或者它们可以嵌套得更深,但它总是只给出嵌套列表的第一个元素。有点希望得到它为什么这样做的幕后答案,而以完全相同的方式编写的函数却没有。

所以我想了解的是为什么它会跳过 for 循环的其他元素。我可以用基本上做同样事情的函数来做一个解决方案。这是代码:

def flat_f(list_x, result):
    try:
        for element in list_x:
            result.append(flat_f(element,result))
    except TypeError:
            return list_x
#removing None values generated by recursive function calls(probably there is a better way of doing this) 
    for index, number in enumerate(result):
        if item==None: del result[index]

所以我不确定为什么它不起作用,这几天一直在敲我的头,如果有人能解释为什么我会非常感激。

yield flat(element).next() 只产生第一个值,然后丢弃嵌套列表的其余部分并继续下一个。使用 yield from.

def flat(list_x):
    for element in list_x:
        try:
            yield from flat(element)
        except TypeError:
            yield element

如果需要支持Python2,将yield from换成循环

def flat(list_x):
    for element in list_x:
        try:
            i = iter(element)
        except TypeError:
            yield element
        else:
            for x in i:
                yield x