';来自'的收益率;Python 2中的替换

';来自'的收益率;Python 2中的替换,python,python-2.7,generator,yield-from,Python,Python 2.7,Generator,Yield From,我的代码用于python3中的递归调用,它工作得非常好。现在的问题是,这是从中引入的,我需要它在中工作。我读了几篇文章,没有一篇足够详细或简单 少数提及的条款: 其他的也很少 我重新创建了一个小样本代码(它接受一个多级列表并返回一个扁平列表),与我的需求相比,它是非常精简的 #python 3 def foo(obj): for ele in obj: if isinstance(ele, list): yield from foo(ele

我的代码用于
python3
中的递归调用,它工作得非常好。现在的问题是,这是从中引入的,我需要它在中工作。我读了几篇文章,没有一篇足够详细或简单

少数提及的条款:

其他的也很少

我重新创建了一个小样本代码(它接受一个多级列表并返回一个扁平列表),与我的需求相比,它是非常精简的

#python 3
def foo(obj):
    for ele in obj:
        if isinstance(ele, list):
            yield from foo(ele)
        else:
            yield ele
#驱动程序值:

>>> l = [1, [2, 3, [4,5]]]
>>> list(foo(l))
=>  [1, 2, 3, 4, 5]

同样的转换在
Python2.7
中不起作用,因为
收益率不可用

您仍然需要循环。这里有递归并不重要

您需要循环递归调用生成的生成器并生成结果:

def foo(obj):
    for ele in obj:
        if isinstance(ele, list):
            for res in foo(ele):
                yield res
        else:
            yield ele
递归调用生成一个生成器,您需要向前传递生成器的结果。通过在生成器上循环并生成各个值来实现

除了升级到Python 3之外,没有更好的选择了

yield from
实质上是将循环的责任传递给调用方,并将任何
generator.send()
generator.throw()调用传递回委托的生成器。您不需要传递
.send()
.throw()
,所以剩下的就是自己负责循环

演示:

yield from
是在(不是PEP 342)中引入的,特别是因为子生成器上的循环不会委托
generator.throw()
generator.send()
信息

政治公众人物明确指出:

如果值的产生是唯一需要考虑的问题,那么使用诸如

for v in g:
    yield v

有一个Python实现等价物,一开始可能看起来很吓人,但您仍然可以发现它循环(使用
而1:
,循环在出现异常或处理
StopIteration
时结束,使用
next()
generator.send(…)
检索新值,并生成结果(使用
yield\y
)。

您仍然需要循环。这里有递归并不重要

您需要循环递归调用生成的生成器并生成结果:

def foo(obj):
    for ele in obj:
        if isinstance(ele, list):
            for res in foo(ele):
                yield res
        else:
            yield ele
递归调用生成一个生成器,您需要向前传递生成器的结果。您可以通过在生成器上循环并生成单个值来实现

除了升级到Python 3之外,没有更好的选择了

yield from
实质上是将循环的责任传递给调用方,并将任何
generator.send()
generator.throw()调用传递回委托的生成器。您不需要传递
.send()
.throw()
,所以剩下的就是自己负责循环

演示:

yield from
是在(不是PEP 342)中引入的,特别是因为子生成器上的循环不会委托
generator.throw()
generator.send()
信息

政治公众人物明确指出:

如果值的产生是唯一需要考虑的问题,那么使用诸如

for v in g:
    yield v
有一个Python实现等价物,一开始可能看起来很吓人,但您仍然可以发现它循环(使用
而1:
,循环在出现异常或处理
StopIteration
时结束,使用
next()
generator.send(…)
检索新值,并生成结果(使用
yield\y
)。

为什么说“我的代码无法处理循环,需要递归”?您可以轻松地在递归生成器中使用循环:

def foo(obj):
    for ele in obj:
        if isinstance(ele, list):
            #yield from foo(ele)
            for t in foo(ele):
                yield t 
        else:
            yield ele

l = [1, [2, 3, [4, 5]]]
print list(foo(l))
输出

[1, 2, 3, 4, 5]
为什么说“我的代码不能处理循环,需要递归”?您可以在递归生成器中轻松使用循环:

def foo(obj):
    for ele in obj:
        if isinstance(ele, list):
            #yield from foo(ele)
            for t in foo(ele):
                yield t 
        else:
            yield ele

l = [1, [2, 3, [4, 5]]]
print list(foo(l))
输出

[1, 2, 3, 4, 5]

为什么它必须是递归的?在内部,从
产生的收益也只是一个循环。然而,从本质上说,从
产生的收益是一个委托循环。你不需要委托,但你仍然需要循环。好吧。我太笨了。它有效。那里的答案有点混乱,我无法理解。让我改变这个问题。注意,
yiePEP 342中没有引入来自
的ld。handles
来自
@MartijnPieters的收益率:notedWhy必须是递归的?从内部来看,来自
的收益率也只是一个循环。然而,从本质上来说,来自
的收益率是一个带有委托的循环。你不需要委托,但你仍然需要循环。好吧。愚蠢的我。它是有效的答案有点混乱,我无法理解。让我改变问题。请注意,PEP 342中没有引入
yield from
。handles
yield from
@MartijnPieters:notedNice answer。一如既往。;)回答不错。一如既往。)