Python空生成器函数
在python中,通过将yield关键字放在函数体中,可以轻松定义迭代器函数,例如:Python空生成器函数,python,generator,Python,Generator,在python中,通过将yield关键字放在函数体中,可以轻松定义迭代器函数,例如: def gen(): for i in range(100): yield i 如何定义一个不产生值(生成0个值)的生成器函数,以下代码不起作用,因为python无法知道它应该是生成器而不是普通函数: def empty(): pass 我可以做类似的事情 def empty(): if False: yield None 但那将是非常丑陋的。有什么
def gen():
for i in range(100):
yield i
如何定义一个不产生值(生成0个值)的生成器函数,以下代码不起作用,因为python无法知道它应该是生成器而不是普通函数:
def empty():
pass
我可以做类似的事情
def empty():
if False:
yield None
但那将是非常丑陋的。有什么好方法可以实现空迭代器函数吗?您可以在生成器中使用
return
一次;它停止迭代而不产生任何结果,因此提供了一种明确的替代方法,以避免函数超出范围。因此,使用yield
将函数转换为生成器,但在函数前面使用return
在生成任何内容之前终止生成器
>>> def f():
... return
... yield
...
>>> list(f())
[]
我不确定它是否比你现在拥有的要好得多——它只是用一个no-opyield
语句替换了一个no-opif
语句。但它更地道。请注意,仅使用yield
不起作用
>>> def f():
... yield
...
>>> list(f())
[None]
为什么不直接使用iter(())?
此问题专门询问空生成器函数。因此,我认为这是一个关于Python语法内部一致性的问题,而不是一个关于创建空迭代器的最佳方法的问题
如果问题实际上是关于创建空迭代器的最佳方法,那么您可能同意使用iter(())
。然而,重要的是要注意,iter(())
不返回函数!它直接返回一个空的iterable。假设您正在使用一个API,该API需要一个可调用函数,该函数每次调用时都返回一个iterable,就像普通的生成器函数一样。您必须执行以下操作:
def empty():
return iter(())
def empty():
return
yield
(给出此答案的第一个正确版本应归功于。)
现在,你可能会发现上面的内容更清晰,但我可以想象在什么情况下,它会变得不那么清晰。考虑一个长的(设计的)生成器函数定义的例子:
def zeros():
while True:
yield 0
def ones():
while True:
yield 1
...
在这个长长的列表的末尾,我更希望看到一些带有收益率的东西,比如:
def empty():
return iter(())
def empty():
return
yield
或者,在Python3.3及更高版本中(如所建议),这是:
yield
关键字的出现,一眼就能清楚地看出,这只是另一个生成器函数,与所有其他函数完全相同。需要更多的时间才能看到iter(())
版本也在做同样的事情
这是一个微妙的区别,但我诚实地认为基于的函数更可读和可维护
还可以从中看到这个很棒的答案,它使用dis
来说明这种方法更可取的另一个原因:它在编译时发出的指令最少。您可以在生成器中使用返回
一次;它停止迭代而不产生任何结果,因此提供了一种明确的替代方法,以避免函数超出范围。因此,使用yield
将函数转换为生成器,但在函数前面使用return
在生成任何内容之前终止生成器
>>> def f():
... return
... yield
...
>>> list(f())
[]
我不确定它是否比你现在拥有的要好得多——它只是用一个no-opyield
语句替换了一个no-opif
语句。但它更地道。请注意,仅使用yield
不起作用
>>> def f():
... yield
...
>>> list(f())
[None]
为什么不直接使用iter(())
?
此问题专门询问空生成器函数。因此,我认为这是一个关于Python语法内部一致性的问题,而不是一个关于创建空迭代器的最佳方法的问题
如果问题实际上是关于创建空迭代器的最佳方法,那么您可能同意使用iter(())
。然而,重要的是要注意,iter(())
不返回函数!它直接返回一个空的iterable。假设您正在使用一个API,该API需要一个可调用函数,该函数每次调用时都返回一个iterable,就像普通的生成器函数一样。您必须执行以下操作:
def empty():
return iter(())
def empty():
return
yield
(给出此答案的第一个正确版本应归功于。)
现在,你可能会发现上面的内容更清晰,但我可以想象在什么情况下,它会变得不那么清晰。考虑一个长的(设计的)生成器函数定义的例子:
def zeros():
while True:
yield 0
def ones():
while True:
yield 1
...
在这个长长的列表的末尾,我更希望看到一些带有收益率的东西,比如:
def empty():
return iter(())
def empty():
return
yield
或者,在Python3.3及更高版本中(如所建议),这是:
yield
关键字的出现,一眼就能清楚地看出,这只是另一个生成器函数,与所有其他函数完全相同。需要更多的时间才能看到iter(())
版本也在做同样的事情
这是一个微妙的区别,但我诚实地认为基于的函数更可读和可维护
另请参见使用dis
来说明此方法更可取的另一个原因的伟大答案:它在编译时发出的指令最少。Python3.3(因为我从kick中获得了收益,而且@senderle偷走了我的第一个想法):
但我必须承认,我很难想出一个这样的用例,iter([])
或(x)range(0)
不会同样好用。python3.3(因为我从
kick中获得了收益,而且@senderle偷走了我的第一个想法):
但我必须承认,我很难想出一个这样的用例,对于这个用例,iter([])
或(x)range(0)
不能同样好地工作。它必须是一个生成器函数吗?如果没有,那怎么办
def f():
return iter(())
它一定是发电机功能吗?如果没有,那怎么办
def f():
return iter(())
另一个选择是:
(_ for _ in ())
另一个选择是:
(_ for _ in ())
你不需要发电机。来吧,伙计们
generator = (item for item in [])
你不需要一个g