欢迎访问宙启技术站
智能推送

Python生成器函数:定义、yield语句、迭代器协议、生成器表达式

发布时间:2023-06-18 22:31:00

Python生成器函数是一种能够动态生成值序列的函数,它使用关键字yield来返回一个值,并且保留函数的当前状态,以便下次调用时能够继续执行代码。生成器函数可以看作是一种特殊的函数,它返回一个生成器对象,而不是一个单独的值或列表。

定义生成器函数

定义生成器函数的方式与定义普通函数类似,只需要在函数体中使用yield语句来返回一个值。下面是一个简单的例子:

def my_generator():
    yield 1
    yield 2
    yield 3

在调用my_generator()函数时,它不会立即执行函数体中的代码,而是返回一个生成器对象。每次调用生成器对象的__next__()方法时,函数会从上一次yield语句执行的地方开始执行,然后一直执行到下一个yield语句处,返回yield语句后面的值。

gen = my_generator()
print(next(gen)) # 1
print(next(gen)) # 2
print(next(gen)) # 3

当函数执行到yield语句时,它的状态会被保存下来,代码会停止执行,然后返回yield语句后面的值。当再次调用生成器对象的__next__()方法时,函数会从上一次yield语句执行的地方开始继续执行,直到下一个yield语句处,再次返回yield语句后面的值。这个过程会一直进行下去,直到函数执行完毕或者被中途停止。

yield语句

yield语句有点类似于return语句,它在函数中返回一个值,但是yield语句不会立即终止函数的执行。当函数执行到yield语句时,它会将值返回给调用者,并且暂停函数的执行,等待下一次调用。

下面是一个例子,展示了如何在生成器函数中使用yield语句来动态生成一个斐波那契数列:

def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b
 
fib = fibonacci()
for i in range(10):
    print(next(fib)) # 0 1 1 2 3 5 8 13 21 34

在这个例子中,生成器函数不会立即计算所有的斐波那契数列,而是使用yield语句在每次循环迭代中生成下一个斐波那契数。当迭代超过10次后,函数停止执行。

迭代器协议

生成器函数也是迭代器,它们遵守迭代器协议。对于迭代器而言,包含两个方法__iter__()和__next__()。__iter__()方法返回迭代器本身,__next__()方法返回下一个元素。

生成器函数的__iter__()方法返回生成器对象本身,__next__()方法实现了yield语句的逻辑,在每次调用时返回下一个值。当所有的值都返回完毕后,__next__()方法会引发StopIteration异常,表示迭代结束。

生成器表达式

除了使用生成器函数来创建生成器对象,Python还提供了一种更简单的方法,使用生成器表达式。生成器表达式与列表推导式类似,但是返回一个生成器对象,而不是一个列表。

下面是一个使用生成器表达式的例子:

gen = (i for i in range(10) if i % 2 == 0)
for i in gen:
    print(i) # 0 2 4 6 8

在这个例子中,使用生成器表达式创建了一个生成器对象,该对象包含10以内所有的偶数。在for循环中使用生成器对象进行迭代时,会依次输出所有的偶数。

总结

Python的生成器函数提供了一种动态生成值序列的方法,它们使用关键字yield来返回值,并且保留函数的当前状态。生成器函数遵循迭代器协议,可以直接使用for循环或者next()函数进行迭代。除了使用生成器函数,Python还支持使用生成器表达式来创建生成器对象,这种方法更加简单直观。