我有以下代码:
import itertools
for c in ((yield from bin(n)[2:]) for n in range(10)):
print(c)
输出结果为:
0
None
1
None
1
0
None
1
1
None
......等为什么会出现None
?如果我改为:
def hmm():
for n in range(10):
yield from bin(n)[2:]
for c in hmm():
print(c)
然后我得到了我的期望:
0
1
1
0
1
1
...等。此外,有没有办法把它写成生成器表达式以获得与后者相同的结果?
答案 0 :(得分:10)
yield
是一个表达式,其值是使用send
发送到生成器的任何值。如果未发送任何内容,则yield
的值为None。在您的示例中,yield from
生成列表中的值,但yield from
表达式本身的值为None,它在封闭生成器表达式的每次迭代时生成(即,{{1的每个值) }})。
您的示例相当于:
range(10)
请注意额外的def hmm():
for n in range(10):
yield (yield from bin(n)[2:])
for item in hmm():
print(item)
。
如果您尝试在生成器表达式中使用yield
,则始终会遇到此问题,因为生成器表达式已经生成了其目标值,因此如果添加显式yield
,则需要添加额外表达式(yield
表达式),其值也将在生成器中输出。换句话说,像yield
之类的东西已经产生(x for x in range(5))
中的数字;如果您执行range(5)
之类的操作,除了数字之外,您还将获得((yield x) for x in range(5))
表达式的值。
据我所知,使用生成器理解无法获得简单的yield
行为(没有额外的Nones)。对于您的情况,我认为您可以使用yield from
:
itertools.chain.from_iterable
(编辑:我意识到你可以通过使用嵌套的for c in itertools.chain.from_iterable(bin(n)[2:] for n in range(10)):
print(c)
子句yield from
获得生成器理解中的for
行为。但是,我认为这不再具有可读性而不是使用x for n in range(10) for x in bin(n)[2:]
。)