Python 生成器

Python 生成器

在Python中,生成器是一种特殊类型的函数,它返回一个迭代器对象。它看起来类似于普通的Python函数,因为它的定义也以def关键字开头。然而,不同于在最后使用return语句,生成器使用yield关键字。

语法

def generator():
 . . .
 . . .
 yield obj
it = generator()
next(it)
. . .

return语句在函数末尾表示函数体的执行结束,所有函数中的局部变量都超出了作用域。如果再次调用函数,则会重新初始化局部变量。

生成器函数的行为不同。它首次被调用时像普通函数一样执行,但当遇到yield语句时,它的执行被暂时暂停,并将控制权返回。产生的结果由调用者消费。调用next()内置函数会从暂停的位置重新开始执行生成器,并生成迭代器的下一个对象。随后的yield会提供迭代器中的下一个项,直到迭代器被耗尽为止。

示例1

下面的代码中的函数是一个生成器,通过yield连续生成1到5的整数。调用时,它返回一个迭代器。每次调用next()都会将控制权传递回生成器并获取下一个整数。

def generator(num):
   for x in range(1, num+1):
      yield x
   return

it = generator(5)
while True:
   try:
      print (next(it))
   except StopIteration:
      break

将产生以下 输出

1
2
3
4
5

生成器函数返回一个动态迭代器。因此,它比从Python序列对象获取的普通迭代器更节省内存。例如,如果你想获取斐波那契序列的前n个数。你可以编写一个普通函数,构建一个斐波那契数列的列表,然后使用循环迭代列表。

示例2

下面是获取斐波那契数列列表的普通函数 –

def fibonacci(n):
   fibo = []
   a, b = 0, 1
   while True:
      c=a+b
      if c>=n:
         break
      fibo.append(c)
      a, b = b, c
   return fibo
f = fibonacci(10)
for i in f:
   print (i)

它将产生以下输出−

1
2
3
5
8

上面的代码将所有的斐波那契数列数字收集到一个列表中,然后使用循环遍历该列表。假设我们想要生成一个包含很大数字的斐波那契数列。在这种情况下,所有的数字都必须被收集到一个列表中,这需要大量的内存。这就是生成器的用处,它生成列表中的单个数字,并将其提供给消费者。

示例3

以下代码是基于生成器的解决方案,用于生成斐波那契数列的列表 –

def fibonacci(n):
   a, b = 0, 1
   while True:
      c=a+b
      if c>=n:
         break
      yield c
      a, b = b, c
   return

f = fibonacci(10)
while True:
   try:
      print (next(f))
   except StopIteration:
      break

异步生成器

异步生成器是一个返回异步迭代器的协程。协程是使用async关键字在Python中定义的函数,它可以调度和等待其他协程和任务。与普通生成器一样,异步生成器在每次调用anext()函数而不是next()函数时,在迭代器中逐步生成项目。

语法

async def generator():
. . .
. . .
yield obj
it = generator()
anext(it)
. . .

示例4

下面的代码演示了一个协程生成器,在每次迭代循环时,生成递增的整数。

import asyncio

async def async_generator(x):
   for i in range(1, x+1):
      await asyncio.sleep(1)
      yield i

async def main():
   async for item in async_generator(5):
      print(item)

asyncio.run(main())

它将产生以下 输出

1
2
3
4
5

示例 5

现在让我们来编写一个生成斐波那契数列的异步生成器。为了在协程内模拟一些异步任务,程序在每次生成下一个数字之前调用sleep()方法,持续1秒钟。结果是,你将在延迟一秒后在屏幕上打印出这些数字。

import asyncio

async def fibonacci(n):
   a, b = 0, 1
   while True:
      c=a+b
      if c>=n:
         break
      await asyncio.sleep(1)
      yield c
      a, b = b, c
   return

async def main():
   f = fibonacci(10)
   async for num in f:
      print (num)

asyncio.run(main())

它将产生以下的 输出

1
2
3
5
8

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程