为什么嵌套“yield from”语句(生成器代理)会生成终止`None`值?

问题描述:

是否可以嵌套yield from陈述?为什么嵌套“yield from”语句(生成器代理)会生成终止`None`值?

简单形式是显而易见的:

def try_yield1(): 
    x = range(3) 
    yield from x 

主要生产:

0 
1 
2 

但如果我有嵌套发电机?

def try_yield_nested(): 
    x = [range(3) for _ in range(4)] 
    yield from ((yield from y) for y in x) 

这将产生:

0 
1 
2 
None # why? 
0 
1 
2 
None # ... 
0 
1 
2 
None # ... 

为什么会产生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) 

其中产生相同的输出,保留了None(这是我期望的那样)。我也可以写一个简单的循环:

for x in [range(3) for _ in range(3)]: 
    yield from x 

但是,我认为这将是更Python使用嵌套代表团(最好连yield from x from yyield from x for x in y,但这不是正确的语法)。为什么它不像我预期的那样工作?

yield是一个表达式,它会评估你的任何你send(value)它。简而言之,如果您不发送任何内容,您将获得None输出,因为yield的值将为None

yield from本身等于None,并且您正在使用其中两个。在第二个yield from中,您正在迭代一个列表,它将生成器与该列表中的项目一起输入,但是您还使用yield from来返回该生成器表达式,该表达式返回列表,并且它自身也会在每次迭代时返回None ,那么为什么在每次迭代范围后,你会得到一个None

本质上讲,这是正在发生的事情:

  1. (yield from y) for y in x得到的值,[0,1,2]
  2. yield from从先前产生的值,并且还从yield from以前这是None
  3. 评估为[0,1,2],然后在(yield from y) for y in x中添加由于yield from而产生的None

不幸的是,由于表达式的性质,没有办法摆脱None输出。你最好用from_iterable

来源解释产量表达; https://docs.python.org/2.5/ref/yieldexpr.html