【Python基础】生成器

文章目录

    • @[toc]
      • 什么是生成器
      • 生成器示例
      • 生成器工作流程
      • 生成器表达式
      • `send()`方法和`close()`方法
        • `send()`方法
        • `close()`方法

因上努力

个人主页:丷从心.

系列专栏:Python基础

学习指南:Python学习指南

果上随缘


什么是生成器

  • Python中,使用生成器可以很方便地支持迭代器协议
  • 生成器通过生成器函数产生,通过def定义,但不是通过return返回,而是通过yield一次返回一个结果,在每个结果之间挂起和继续它们的状态,来实现迭代器协议
  • yield本质上是一个语法糖,内部是一个状态机,维护着挂起和继续的状态,从而支持迭代器协议

生成器示例

def my_range(n):
    i = 0
    while i < n:
        yield i

        i += 1


my_range = my_range(3)

print(my_range)

print(next(my_range))
print(next(my_range))
print(next(my_range))
<generator object my_range at 0x0000019CE75804A0>
0
1
2
  • 在这个例子中,定义了一个生成器函数my_range()
  • 调用生成器函数会返回一个生成器对象,本质上是返回生成器对象的迭代器,通常直接称为生成器
  • 既然生成器本质上是一个迭代器,那么其内部需要实现__iter__()方法和__next__()方法,dir()函数可以获取一个对象的所有属性和方法,可以使用dir()函数查看生成器对象的属性和方法
def my_range(n):
    i = 0
    while i < n:
        yield i

        i += 1


my_range = my_range(3)

print(dir(my_range))

print('__iter__' in dir(my_range))
print('__next__' in dir(my_range))
['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw']
True
True

生成器工作流程

  • 在上面的例子中加入一些打印信息,进一步看看生成器的工作流程
def my_range(n):
    print('开始迭代...')
    print('-' * 10)

    i = 0
    while i < n:
        print('迭代中...')

        yield i

        print('-' * 10)

        i += 1

        print('迭代结束')


gen_obj = my_range(3)

print(next(gen_obj))
print(next(gen_obj))
print(next(gen_obj))
开始迭代...
----------
迭代中...
0
----------
迭代结束
迭代中...
1
----------
迭代结束
迭代中...
2

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 通过结果可以看到:
    • 当调用生成器函数的时候,函数只是返回了一个生成器对象,并没有运行
    • 当第一次调用next()方法的时候,生成器函数才开始运行,运行到yield语句处停止,并将i作为返回值返回,执行过程为图中的①②
    • 当继续调用next()方法的时候,生成器函数从上一次停止的地方,也就是yield语句处继续运行,直到再次运行到yield语句处停止, 并将i作为返回值返回,执行过程为图中的③④②
    • 如果下一次迭代不能运行到yield语句,就抛出StopIteration异常,生成器在当前yield语句处停止,不再执行③④②过程

生成器表达式

  • 在介绍生成器表达式之前,先看看我们已经比较熟悉的列表解析
nums = [i for i in range(10) if i % 2]

print(nums)
[1, 3, 5, 7, 9]
  • 上述列表解析返回一个包含 1 1 1 10 10 10之间所有奇数的列表
  • 当序列很长,而每次只需要获取一个元素时,应当考虑生成器而不是列表解析
  • 生成器表达式的语法和列表解析一样,只不过生成器表达式是被()括起来的
gen_obj = (i for i in range(10) if i % 2)

print(gen_obj)
<generator object <genexpr> at 0x000001D6DC1E04A0>
  • 生成器表达式并不是返回一个列表,而是返回一个生成器
  • 使用生成器时,每迭代一次会产生(yield)出一个值来,实现了惰性加载(懒加载),只有在被迭代时才被赋值,并覆盖上一个值,所以在序列较长的情况下,使用生成器会优化内存

send()方法和close()方法

  • 生成器中有两个重要的方法:send()方法和close方法
send()方法
  • Python 2.5中,yield语句变成了yield表达式,也就是说yield可以有一个值,而这个值就是send()方法的参数,通过调用send()方法将值传递给yield,而send()的返回值为yield返回的值,所以send(None)next()是等效的
  • 注意,调用send()传入非None值前,生成器必须处于挂起状态,否则将抛出异常,也就是说,第一次运行生成器时,只能使用next()send(None),因为没有yield来接收这个值
def my_range(n):
    i = 0
    while i < n:
        var = yield i

        print(f'var 的值为 {var}')

        i += 1


my_range = my_range(3)

print(my_range.send(None))
print(my_range.send('hello'))
print(my_range.send('world'))
0
var 的值为 hello
1
var 的值为 world
2
close()方法
  • close()方法用于关闭生成器,对关闭后的生成器再次调用next()send()将抛出StopIteration异常
def my_range(n):
    i = 0
    while i < n:
        var = yield i

        print(f'var 的值为 {var}')

        i += 1


my_range = my_range(3)

print(my_range.send(None))
print(my_range.send('hello'))

my_range.close()

print(my_range.send('world'))
0
var 的值为 hello
1
Traceback (most recent call last):
  File "C:/Users/FOLLOW_MY_HEART/Desktop/Python基础/【Python基础】生成器/test.py", line 18, in <module>
    print(my_range.send('world'))
StopIteration

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/525523.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Longan Pi 3H 开发板体验

Longan Pi 3H 开发板体验 开箱内容 打开包装&#xff0c;你可以看到以下物品 一个Longan Pi 3H盒子Longan Pi 3H开发板 产品基本介绍 Longan Pi 3H 是基于 Longan Module 3H 核心板的 ARM Linux 开发板&#xff0c;以 H618 (Quad core ARM Cortex-A531.5Ghz , 64-bit) 为主控…

合并主分支到子分支

参考&#xff1a;【Git】合并分支出现 Please enter a commit message to explain why this merge is necessary.-CSDN博客 git 如何将主分支(master)合并到子分支上_git 将主分支合并到子分支-CSDN博客 1、先切换到主分支master git checkout master 2、把主分支代码拉到本地…

小程序实现订阅功能和测试发送订阅信息

现在一次性订阅是只能用户点一次才能发送一次&#xff0c;而针对长期模板只有规定的几种类目政务、民生、交通等等的才可以&#xff0c;所以说感觉这功能其实已经不是很适合使用了&#xff0c;只适合一些特别的场景才可以使用。 地址&#xff1a;https://developers.weixin.qq…

【排列回溯】Leetcode 46. 全排列 47. 全排列 II

【排列回溯】Leetcode 46. 全排列 47. 全排列 II 46 全排列——used数组上下层保证不取重复的即可47. 全排列 II——used去重上下层&#xff0c;再去重本层重复元素 46 全排列——used数组上下层保证不取重复的即可 ---------------&#x1f388;&#x1f388;题目链接&#x…

2024年面试AI编译器岗经验总结

面试经历: 面试中必备的知识: 1.用C++实现一个卷积 (图解)一步一步使用CPP实现深度学习中的卷积 - GiantPandaCVGiantPandaCVhttp://giantpandacv.com/academic/%E7%AE%97%E6%B3%95%E7%A7%91%E6%99%AE/%E5%B0%BD%E8%A7%88%E5%8D%B7%E7%A7%AF%E7%A5%9E%E7%BB%8F%E7%BD%91%E…

Springboot引入swagger

讲在前面&#xff1a;在spring引入swagger时&#xff0c;由于使用的JDK、Spring、swagger 的版本不匹配&#xff0c;导致启动报错&#xff0c;一直存在版本依赖问题。所以在此声明清楚使用版本。JDK 1.8、Spring boot 2.6.13、 Swagger 2.9.2。 引入maven依赖 <dependency&…

Mysql【索引覆盖、索引下推、索引合并、索引跳跃】介绍

索引覆盖、索引下推、索引合并、索引跳跃都是Mysql对索引的优化手段&#xff0c;它们的思想就是尽量让查询数据走索引&#xff0c;那它们有什么区别呢&#xff1f; 一、首先介绍一下MySQL体系结构 上图来自MySQL官方文档。 通常把MySQL从上至下分为以下几层&#xff1a; MySQ…

备考ICA----Istio实验18---单集群中部署多个Istio控制面

备考ICA----Istio实验18—单集群中部署多个Istio控制面 单个 Kubernetes 控制面以及多个 Istio 控制面和多个网格。通过 Kubernetes 命名空间和 RBAC 实现软多租户业务隔离。 1. 环境准备 1.1 创建2个命名空间 kubectl create ns usergroup-1 kubectl label ns usergroup-…

外包干了6天,技术明显进步

先说一下自己的情况&#xff0c;本科生&#xff0c;2019年我通过校招踏入了南京一家软件公司&#xff0c;开始了我的职业生涯。那时的我&#xff0c;满怀热血和憧憬&#xff0c;期待着在这个行业中闯出一片天地。然而&#xff0c;随着时间的推移&#xff0c;我发现自己逐渐陷入…

探索Kubernetes的大二层网络:原理、优势与挑战

在云原生领域&#xff0c;Kubernetes (K8s) 已经成为容器编排的事实标准☁️&#x1f4e6;。为了支撑其灵活的服务发现和负载均衡&#x1f50d;&#x1f504;&#xff0c;K8s采用了大二层网络的设计理念&#x1f578;️。本文将深入探讨大二层网络的工作原理、带来的好处✨&…

在线JSON工具

功能支持 ctrls json格式化游览器本地保存ctrla ctrlc 自动检测选中范围是否是全选&#xff0c;然后按照格式化方式添加到粘贴板中json 粘贴JSON自动格式化json可视化修改json压缩复制json层级折叠json关键key 搜索(自动提示高亮)满足某些近视的可以自行调整字体大小, 并且会游…

敦煌网、速卖通、国际站铺需要自养号补单来稳定出单率吗?

亚马逊、速卖通、Lazada、shoppe、速卖通、敦煌网、Temu、shein、美客多、阿里国际、卖家如何保证店铺出单稳定?在竞争激烈的平台上&#xff0c;保持店铺的稳定出单是每个卖家都追求的目标。为了实现这一目标&#xff0c;卖家需要综合考虑产品、运营、客户服务等多个方面的因素…

推动科技创新润德生物邀您到场参观2024第13届生物发酵展

参展企业介绍 山东润德生物科技有限公司成立于2014年10月17日&#xff0c;是一家围绕生物制品的研发、生产、营销、国际贸易、技术服务为核心业务的国家高新技术企业&#xff0c;近年来荣获国家制造业单项冠军示范企业、国家级绿色工厂、国家知识产权优势企业、国家工业产品绿…

Nacos Namespace 未授权访问漏洞

Nacos Namespace 未授权访问漏洞 问题 nacos 源码启动&#xff0c;发现即使开启了鉴权&#xff1a;nacos.core.auth.enabledtrue&#xff0c;未登录情况下&#xff0c;命名空间列表接口仍旧能查询到数据 鉴权逻辑 通过**AuthFilter **进行权限校验判断方法上是否存在注解 …

电脑硬件 - 硬盘

硬盘是一台电脑的数据中心&#xff0c;存放着我们用户的所有文件和数据 对于一块硬盘&#xff0c;其重要指标&#xff1a;顺序读写能力&#xff0c;随机读写能力 顺序读写影响大文件的拷贝&#xff0c;随机读写影响大量小文件的拷贝&#xff08;打开软件的快慢&#xff09; 因…

Chatgpt掘金之旅—有爱AI商业实战篇|内容策展业务|(八)

演示站点&#xff1a; https://ai.uaai.cn 对话模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 一、AI技术创业内容策展业务有哪些机会&#xff1f; 人工智能&#xff08;AI&#xff09;技术作为当今科技创新的前沿领域&#xff0c;为创业者提供了广阔的机会和挑战。随着…

蓝色系UX/UI设计求职面试作品集模版figmasketchPPT可编辑源文件

页面数量: 20P 页面尺寸:1920*1080PX 交付格式&#xff1a;figma、sketch、PPT 赠送文件&#xff1a;24款高质量样机&#xff08;PSD格式&#xff09; 该作品集虽然只有20页&#xff0c;但可根据需求复制作品集里已有的页面作为模版来扩展您的设计项目 该作品集模版可编辑可修…

蓝桥杯嵌入式备考笔记

这里写目录标题 keil配置LED-KEY-LCDledkeyLCD最多21位 RTCPWM捕获占空比ADCI2C按键长按uartPWMDAC双击高亮EEp初始化LED闪烁时间倒计时 keil配置 LED-KEY-LCD 留下这几个 按键 创建俩个文件写代码&#xff0c;记得把这两个文件加进工程 led uwTick 1ms执行一次 写错…

基于springboot实现教师人事档案管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现IT技术交流和分享平台系统演示 摘要 我国科学技术的不断发展&#xff0c;计算机的应用日渐成熟&#xff0c;其强大的功能给人们留下深刻的印象&#xff0c;它已经应用到了人类社会的各个层次的领域&#xff0c;发挥着重要的不可替换的作用。信息管理作为计算…

C语言语法最后一个教案-教案21(预处理 · 头文件)

最近给大家争取到一个 深夜福利 保证你在深夜手机刷到 嘎嘎香~ 那就是 官方授权 大流量卡 缺点&#xff1a;月租太便宜 185GB~ 100分钟通话时长~ 长期套餐~ 畅想自由的气息 流量自由的同时还拥有超长通话&#xff0c;而且免费领取。 名额有限&#xff0c;咱们废话不…