Python 提供了一个生成器来创建自己的迭代器函数。 生成器是一种特殊类型的函数,它不返回单个值,而是返回一个包含一系列值的迭代器对象。 在生成器函数中,使用yield
语句,而不是返回语句。 下面是一个简单的生成器函数。
Example: Generator Function
def mygenerator():
print('First item')
yield 10
print('Second item')
yield 20
print('Last item')
yield 30
在上面的例子中,mygenerator()
函数是一个生成器函数。它使用yield
而不是 return 关键字。 因此,这将在每次调用yield
关键字时返回该值。但是,您需要为此函数创建一个迭代器,如下所示。
Example: next()
>>> gen = mygenerator()
>>> next(gen)
First item
10
>>> next(gen)
Second item
20
>>> next(gen)
Last item
30
生成器函数不能包含return
关键字。如果包含它,那么它将终止函数。 yield
和return
的区别在于yield
返回值并暂停执行,同时保持内部状态,而return
语句返回值并终止函数的执行。
以下生成器函数包含 return 关键字。
Example: return in Generator Function
def mygenerator():
print('First item')
yield 10
return
print('Second item')
yield 20
print('Last item')
yield 30
现在,如下所示执行上述功能。
Example: Generator Function
>>> gen = mygenerator()
>>> next(gen)
First item
10
>>> next(gen)
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
it.__next__()
StopIteration
如您所见,上面的生成器在获取第一项后停止执行,因为 return 关键字是在yield
获取第一项后使用的。
用于具有生成器功能的循环
生成器函数也可以使用 for
循环。
Example: Use For Loop with Generator Function
def get_sequence_upto(x):
for i in range(x):
yield i
如上图所示,get_sequence_upto
函数使用了yield
关键字。 发电机的调用就像正常功能一样。 然而,当遇到yield
关键字时,其执行被暂停。这将迭代器流的第一个值发送到调用环境。但是,局部变量及其状态保存在内部。
上面的生成器函数get_sequence_upto()
可以如下调用。
Example: Calling Generator Function
>>> seq = get_sequence_upto(5)
>>> next(seq)
0
>>> next(seq)
1
>>> next(seq)
2
>>> next(seq)
3
>>> next(seq)
4
>>> next(seq)
Traceback (most recent call last):
File "<pyshell#13>", line 1, in <module>
it.__next__()
StopIteration
当向迭代器对象发出 next() 时,该函数恢复。当next()
遇到StopIteration
错误时,该功能最终终止。
在下面的例子中,函数square_of_sequence()
充当一个生成器。它在每次调用 next() 时连续产生一个数字的平方。
Example:
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
循环。
Output
Received on next(): 0
Received on next(): 1
Received on next(): 4
Received on next(): 9
Received on next(): 16
我们可以使用 for
循环遍历生成器上的元素。在这种情况下,next()
函数被隐式调用,StopIteration
也被自动处理。
Example: Generator with the For Loop
squres = square_of_sequence(5)
for sqr in squres:
print(sqr)
Output
0
1
4
9
16
*Note:*One of the advantages of the generator over the iterator is that elements are generated dynamically. Since the next item is generated only after the first is consumed, it is more memory efficient than the iterator. *## 生成器表达式
Python 还提供了一个生成器表达式,这是定义简单生成器函数的一种更短的方式。生成器表达式是匿名生成器函数。以下是square_of_sequence()
函数的生成器表达式。
Example: Generator Expression
>>> squres = (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
循环。
生成器表达式也可以在函数中传递。它应该不带括号传递,如下所示。
Example: Passing Generator Function
>>> import math
>>> sum(x*x for x in range(5))
30
在上面的例子中,一个没有括号的生成器表达式被传递到内置函数sum
中。***