Reu*_*ani 5 python yield generator python-3.x yield-from
是否可以嵌套yield from语句?
简单的形式是显而易见的:
def try_yield1():
x = range(3)
yield from x
Run Code Online (Sandbox Code Playgroud)
哪个产生:
0
1
2
Run Code Online (Sandbox Code Playgroud)
但是,如果我有嵌套的生成器怎么办?
def try_yield_nested():
x = [range(3) for _ in range(4)]
yield from ((yield from y) for y in x)
Run Code Online (Sandbox Code Playgroud)
这会产生:
0
1
2
None # why?
0
1
2
None # ...
0
1
2
None # ...
Run Code Online (Sandbox Code Playgroud)
None如果我使用yield from它(为什么它是嵌套的)它为什么会产生?
我知道我可以这样做:
from itertools import chain
def try_yield_nested_alternative():
x = [range(3) for _ in range(4)]
yield from chain.from_iterable(x)
Run Code Online (Sandbox Code Playgroud)
这产生相同的输出而忽略了None(这是我期望的).我也可以写一个简单的循环:
for x in [range(3) for _ in range(3)]:
yield from x
Run Code Online (Sandbox Code Playgroud)
但是,我认为使用嵌套委托会更加pythonic(最好是偶数yield from x from y或者yield from x for x in y,但这不是正确的语法).为什么它没有像我期望的那样工作?
小智 7
yield是一个表达,它会评估你的send(value)一切.简单地说,如果你把它什么都没有,你会得到一个None输出,因为价值yield会None.
yield from本身等于None,你正在使用其中两个.在第二个yield from你正在迭代一个列表,它输入生成器与该列表的项目,但你也yield from用来返回该生成器表达式,它返回列表和自身,这相当于None每次迭代,这就是为什么在每个项目迭代范围之后,你得到一个None.
基本上这就是发生的事情:
(yield from y) for y in x 产生值,[0,1,2]yield from产生前一个值,也yield from来自之前的值None.None到期yield from的(yield from y) for y in x.不幸的是None,由于表达式的性质,没有办法摆脱输出.你最好不要使用from_iterable.
来源解释产量表达; https://docs.python.org/2.5/ref/yieldexpr.html