python函数返回生成器或普通对象时出现问题
我将函数python函数返回生成器或普通对象时出现问题,python,iteration,generator,yield,Python,Iteration,Generator,Yield,我将函数f定义为 def f(flag): n = 10 if flag: for i in range(n): yield i else: return range(n) 但是f返回一个生成器,无论标志是什么: >>> f(True) <generator object f at 0x0000000003C5EEA0> >>> f(False) <gener
f
定义为
def f(flag):
n = 10
if flag:
for i in range(n):
yield i
else:
return range(n)
但是f
返回一个生成器,无论标志是什么:
>>> f(True)
<generator object f at 0x0000000003C5EEA0>
>>> f(False)
<generator object f at 0x0000000007AC4828>
它看起来像f(False)
返回一个经过迭代的生成器。原因是什么?谢谢。包含yield
语句的函数总是返回生成器对象
只有在遍历该生成器对象时,才会执行函数中的代码。在此之前,函数中不会执行任何代码,Python无法知道您将返回
请注意,在生成器函数中使用return
与在常规函数中使用不同的语义<代码>返回
在这种情况下,只被视为“在此处退出生成器”;返回值被丢弃,因为生成器只能通过yield
表达式生成值
看起来您想使用从
获得的收益:
def f(flag):
n = 10
if flag:
for i in range(n):
yield i
else:
yield from range(n)
yield from
需要Python 3.3或更高版本
请参阅文档:
在函数体中使用yield
表达式会使该函数成为生成器
调用生成器函数时,它返回一个称为生成器的迭代器。然后,该生成器控制生成器功能的执行。当调用生成器的一个方法时,执行开始。此时,执行继续到第一个yield
表达式,在那里它再次被挂起,将expression\u list的值返回给生成器的调用者
对生成器的迭代调用,触发执行
如果您希望在某些时候返回生成器,则不要在此函数中使用yield
。你可以用其他方法生产发电机;例如,使用单独的函数,或者使用生成器表达式:
def f(flag):
n = 10
if flag:
return (i for i in range(n))
else:
return range(n)
现在在
f
中不再使用yield
,它将不再直接生成生成器对象。相反,生成器表达式(i表示范围(n)中的i))
会生成它,但只能有条件地生成它。您可以通过使用实际使用yield的嵌套函数来解决此问题:
def f(flag):
def gen():
for i in range(n):
yield i
n = 10
if flag:
return gen()
else:
return range(n)
>>> f(True)
<generator object gen at 0x7f62017e3730>
>>> f(False)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
如果一个函数中有一个yield
,即使是无法达到的,它始终是一个生成器。
def f(flag):
def gen():
for i in range(n):
yield i
n = 10
if flag:
return gen()
else:
return range(n)
>>> f(True)
<generator object gen at 0x7f62017e3730>
>>> f(False)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
def map(self, fn, *iterables, timeout=None):
if timeout is not None:
end_time = timeout + time.time()
fs = [self.submit(fn, *args) for args in zip(*iterables)]
# Yield must be hidden in closure so that the futures are submitted
# before the first iterator value is required.
def result_iterator():
try:
for future in fs:
if timeout is None:
yield future.result()
else:
yield future.result(end_time - time.time())
finally:
for future in fs:
future.cancel()
return result_iterator()