Python - 生成器函数
2023-09-17 22:17:26
Python提供了一个生成器来创建自己的iterator function。
生成器是一种特殊类型的函数,它不返回单个值,而是返回具有一系列值的迭代器对象。
在生成器函数中,使用 yield
语句而不是 return 语句。
下面是一个简单的生成器函数。
def mygenerator():
print('First item')
yield 10
print('Second item')
yield 20
print('Last item')
yield 30
在上面的示例中,mygenerator()
函数是一个生成器函数。它使用 yield
而不是返回关键字。
因此,这将在每次调用 yield
关键字时返回该值。但是,您需要为此函数创建一个迭代器,如下所示。
gen = mygenerator()
val = next(gen) #First item
print(val) #10
val = next(gen) #Second item
print(val) #20
val = next(gen) #Last item
print(val) #30
val = next(gen) #error
生成器函数不能包含 return
关键字。如果包含它,则它将终止函数。
yield
和 return
之间的区别在于,yield
返回一个值并暂停执行,同时保持内部状态,而 return
语句返回一个值并终止函数的执行。
以下生成器函数包括返回关键字。
def mygenerator():
print('First item')
yield 10
return
print('Second item')
yield 20
print('Last item')
yield 30
现在,执行上述函数,如下所示。
gen = mygenerator()
gen = mygenerator()
val = next(gen) #First item
print(val) #10
val = next(gen) #error
如您所见,上面的生成器在获取第一项后停止执行,因为在yield
第一项后使用了 return 关键字。
将 for 循环与生成器功能结合使用(Using for Loop with Generator Function)
生成器函数也可以使用 for 循环。
def get_sequence_upto(x):
for i in range(x):
yield i
正如您在上面看到的,get_sequence_upto
函数使用 yield
关键字。
生成器的调用就像普通函数一样。
但是,在遇到 yield
关键字时,其执行将暂停。这会将迭代器流的第一个值发送到调用环境。但是,局部变量及其状态在内部保存。
上述生成器函数get_sequence_upto()
可以调用如下。
seq = get_sequence_upto(5)
print(next(seq)) #0
print(next(seq)) #1
print(next(seq)) #2
print(next(seq)) #3
print(next(seq)) #4
print(next(seq)) #error
当向迭代器对象发出next()时,函数将恢复。当next()
遇到StopIteration
错误时,该函数最终终止。
在下面的示例中,函数 square_of_sequence()
充当生成器。它在每次调用next()时依次产生一个数字的平方。
def square_of_sequence(x):
for i in range(x):
yield i*i
以下脚本演示如何调用上述生成器函数。
gen=square_of_sequence(5)
while True:
try:
print ("Received on next(): ", next(gen))
except StopIteration:
break
上面的脚本使用 try..except
块来处理StopIteration
错误。一旦捕获到StopIteration
错误,它将中断 while 循环。
输出:
Received on next(): 0
Received on next(): 1
Received on next(): 4
Received on next(): 9
Received on next(): 16
我们可以使用 for 循环遍历生成器上的元素。在这种情况下,将隐式调用next()
函数,并且还会自动处理StopIteration
。
squres = square_of_sequence(5)
for sqr in squres:
print(sqr)
输出:
0
1
4
9
16
注意: 生成器相对于迭代器的优点之一是元素是动态生成的。由于下一项仅在使用第一项后生成,因此它比迭代器更节省内存。
生成器表达式(Generator Expression)
Python 还提供了生成器表达式,这是定义简单生成器函数的较短方法。
生成器表达式是一个匿名生成器函数。下面是 square_of_sequence()
函数的生成器表达式。
squre = (x*x for x in range(5))
print(next(squre)) #0
print(next(squre)) #1
print(next(squre)) #4
print(next(squre)) #9
print(next(squre)) #16
在上面的示例中,(x*x for x in range(5))
是一个生成器表达式。表达式的第一部分是yield
值,第二部分是集合的 for 循环。
生成器表达式也可以在函数中传递。它应该不带括号,如下所示。
import math
val = sum(x*x for x in range(5))
print(val)
在上面的示例中,生成器表达式不带括号传递到内置函数 sum
中。
本文内容总结: