Python系列 37 生成器

本文深入探讨Python生成器,包括生成器函数、斐波拉契数列、生成器表达式、send()和close()方法,以及yield from的使用。生成器是迭代器的高效实现,避免了大容量数据存储的内存问题。通过示例代码展示了如何创建和使用生成器,以及生成器在函数栈帧中的工作原理。
摘要由CSDN通过智能技术生成

生成器

生成器(generator)是迭代器的一种特殊实现方式,有2种方式可以创建,一种是通过生成器函数创建,另一种是生成器表达式进行创建。

生成器继承了迭代器的一切优点,简而言之是迭代器的一种升级版本。

在前面的迭代器一章节中介绍过,如果要想获取一个迭代器,必须要先创建一个可迭代对象,然后调用其下的__iter__()方法才能拿到一个迭代器,这样做会产生一些问题,如下所示:

  • 我们只想要一个迭代器,并不需要可迭代对象的前提下该怎么办
  • 可迭代对象中的数据项会占据大量内存空间,如果要想获取1个含有1000万个数据项的列表迭代器,则必须先创建1个列表对象,再获取其专属的迭代器,虽然迭代器不耗费内存,但是可迭代对象必然耗费内存

而生成器则是简化了这种操作,只需要创建生成器函数就可以拿到一个单纯的迭代器。

如果要判断一个对象是否属于生成器,推荐使用collections.abc下的Generator进行判定:

>>> from collections.abc import Generator
>>> isinstance(list,Generator)
False

生成器函数

如果一个函数中出现yield关键字,则它就是一个生成器函数,当一个生成器函数加括号进行调用时,并不会立即运行逻辑体代码,而是返回一个生成器对象。

当对这个生成器对象调用next()方法时,将启动该生成器对象,生成器对象开始执行函数逻辑体代码。

而在执行函数逻辑体代码时如果碰见yield则会发生2件事情:

  • 返回yield后面的值,类似于return函数
  • 挂起当前生成器函数的运行状态,而不是结束生成器函数的运行,也就是说这个生成器对象不会被销毁

再次对生成器对象调用next()方法时恢复暂停状态,继续上述流程进行运行。

一个简单的例子:

def generatorFunction():
    n = 3
    while n:
        yield n
        n-=1
    # return None ❶

# ❷
generatorObject = generatorFunction()
print(generatorObject)

# ❸
print(next(generatorObject))
print(next(generatorObject))
print(next(generatorObject))

# ❹
print(next(generatorObject))

# <generator object generatorFunction at 0x10b5afdb0> 
# 3
# 2
# 1
# StopIteration

❶:默认的函数返回值即为None,在Python3之前的较低版本中,return关键字和yield关键字不可以同时出现在一个函数中,但是目前已经取消了这种设定

❷:生成器函数加括号,返回生成器对象

❸:生成器对象调用next()方法,开始执行函数体代码

❹:由next()方法抛出的StopIteration异常ÿ

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值