成为Python大牛必须要掌握的高端语法——yield
1. 什么是yield
在介绍yield语法之前,首先要向大家说明Python中的迭代(iteration)、可迭代(iterable)、迭代器(iterator)以及生成器(Generator)的概念:
迭代是一种对数据的操作,例如针对一个list逐一获取其中的元素的过程就叫做迭代。而可迭代是对象的一种特性,迭代操作只能针对拥有可迭代特性的对象进行,常见的可迭代对象包括数组、元组、字典等数据集合,下面代码给大家演示了一个基本的迭代过程:
迭代器也是一种可迭代对象,与普通的可迭代对象的区别在于,迭代器内部实现了next函数用来生成每次迭代循环需要返回的元素。而最后的生成器则又是一种特殊的迭代器,具体体现上就是使用yield语法的函数,讲到这里就提到了yield语法,总的来说yield就是用来产生一个生成器的语法,例如将上述的迭代过程修改为生成器方式可以这样写:
迭代器也是一种可迭代对象,与普通的可迭代对象的区别在于,迭代器内部实现了next函数用来生成每次迭代循环需要返回的元素。而最后的生成器则又是一种特殊的迭代器,具体体现上就是使用yield语法的函数,讲到这里就提到了yield语法,总的来说yield就是用来产生一个生成器的语法,例如将上述的迭代过程修改为生成器方式可以这样写:
上述代码的my_generator()即返回了一个生成器对象,每次循环时执行到yield处即返回当时的index的值,到下一次循环时将从上次返回的yield处继续执行,直到index的值不满足小于5的条件时结束整个函数,此时也结束了对这个生成器的迭代过程。
这四者之间的关系可能会稍微有些混乱,再给大家简单的总结一下:生成器是一种特殊的迭代器,而迭代器又是一种特殊的可迭代对象,可迭代对象就是可以执行迭代操作也就是可以通过for循环来遍历的对象。
本文福利:私信小编【PDF】可获取小编精心整理的电子书一套
2. 为什么要使用yield
看了上述两个迭代过程,大家可能有些疑问,使用yield改造成生成器方式的代码看起来比简单的迭代一个列表的方式要复杂许多,那么这样写有什么优势呢?
首先,使用yield语法的生成器最主要的一个优势就是极其省内存。例如上述两个迭代过程,同样是遍历输出0-4这几个元素,使用列表的方式需要构建出一个长度为5的数组并存储在内存中,而使用生成器的方式只需要一个index变量即可实现,这还是迭代元素较少的情况下,如果迭代的是100万甚至1000万个元素时,列表的方式就需要构建一个长度为100万或者1000万的数组,这时对于内存的使用就是非常大的负担了,而使用生成器的方式,无论是迭代100万还是1000万个元素,依然只需要一个index变量即可实现。
并且生成器的方式是即用即计算的,即迭代到对应的元素时,这个元素才相应的计算生成出来,而列表的方式需要在迭代开始前就构建出整个迭代数组,这在某些情况下可以极大地节省计算时间。例如下面这段代码:
.在学习中有迷茫不知如何学习的朋友小编推荐一个学Python的学习q u n 227 -435- 450可以来了解一起进步一起学习!免费分享视频资料
这段代码中,实际的迭代过程只进行到第10个元素即退出了整个循环,但是在迭代开始前,依然要计算1000万次来生成迭代列表,这就造成了大量的计算和内存资源。而如果通过生成器重写该迭代过程的话:
生成器在迭代开始前并不会计算出所有需要迭代的值,只有用到时才会计算相应的值并返回,因此上述代码的index将只会计算到10即结束了整个迭代过程,避免了计算和内存资源的浪费。
3. yield语法示例1:DIY一个range函数
Python自带的range函数可以产生一个可迭代对象,常用于for循环中,在Python 2中range函数生成的是一个列表,而在Python 3中range函数生成的是一个生成器。现在让我们来通过yield语法DIY一个自己的range生成器吧!
我们首先构造一个返回给定范围数组的函数:
这个函数接受两个int类型的参数,分别为数组的开始和结束,每个数之间间隔为1,我们还可以通过增加一个参数来指定两个数之间的间隔,实现函数更高的灵活性:
我们先来运行测试一下这个range函数:
上述代码的输出结果如下:
2
4
6
输出结果符合我们的预期,现在通过yield语法来将我们自己DIY的range函数改造成一个生成器:
改造起来也非常简单,首先将定义的用来存储迭代元素的列表删除,然后将原来添加元素到列表中的代码改造成yield start即可,这样我们就自己DIY了一个简易的、基于生成器实现的range函数。
4. yield语法示例2:读取文件--《告白气球》
生成器除了可以用于计算生成数字元素外,在IO读取方面也能起到很大作用,例如在读取一个超大文件,或者查询某个返回结果超多的数据库时,使用通过yield语法构造的生成器来完成读取操作可以很大程度上降低程序对于内存的占用。
例如我们有一个名为my_file.txt的文件,里面存储了周董的《告白气球》的歌词,现在我们可以通过yield语法来构造一个生成器用于一行一行的读取每一句歌词:
这里使用with语法来读取文件,这是Python 3推荐的方式。file.readline()函数每次返回一行内容,由于返回的内容带有每行结尾的换行符,因此通过line.strip(‘ ’)将换行符过滤掉。每次通过yield返回一行内容之后,再次通过file.readline()函数获取下一行内容,直到整个文件被完全迭代。
让我们来运行测试一下这个按行读取文件内容的生成器:
上述代码的输出结果如下:
塞纳河畔 左岸的咖啡
我手一杯 品尝你的美
留下唇印 的嘴
……
《告白气球》的歌词就一行一行的输出到屏幕上了,由于歌词行数过多,因此这边只复制出前三行给大家演示结果。
5. yield语法示例3:斐波那契数列
斐波那契数列是一道经典的算法题,也是程序员面试时经常会被问到的一道题。斐波那契数列的就是一个形如1, 1, 2, 3, 5, 8, ……的数列,从第三项开始,每一项都等于前两项之和。使用Python来实现一个计算斐波那契数列的典型函数如下:
这个函数通过一个名为fib_list的数组存储生成的前n个斐波那契数,最后一次性返回整个数组。其中a, b = b, a + b是Python的一个特色用法,用于快速交换两个数,相当于:
参考之前DIY的range函数的写法,将这个计算斐波那契数列的函数通过yield语法修改为生成器:
让我们来测试运行一下这个通过yield语法实现的斐波那契数列生成器:
对应的输出结果为:
1
1
2
3
5
可以看到,从第三项开始的每一项都是前两项的和,这样的输出结果就是我们要的斐波那契数列。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
开源干货!!!.NET Core + Vue.js(iview-admin) 通用动态权限(RBAC)管理系统框架[DncZeus]开源啦!...
DncZeus 前言 关于 DncZeus DncZeus = Dnc + Zeus "Dnc"--.Net Core 的缩写; "Zeus"--中文译为宙斯,是古希腊神话中的众神之王,奥林匹斯十二主神之首,统治宇宙万物的至高无上的主神(在古希腊神话中主神专指宙斯),人们常用“众神和人类的父亲”、“神王”来称呼他,是希腊神话诸神中最伟大的神。 DncZeus的愿景就是做一个.NET Core 领域的简易精致的通用后台权限管理模板系统基础框架,努力向.NET Core 领域的"宙斯"看齐。 项目简介 DncZeus是一个基于 ASP.NET Core 2 + Vue.js 的前后端分离的通用后台管理系统框架。后端使用.NET Core 2 + Entity Framework Core 构建,UI 则是目前流行的基于 Vue.js 的 iView。项目实现了前后端的动态权限管理和控制以及基于 JWT 的用户令牌认证机制,让前后端的交互更流畅。 DncZeus并不是一个完整的业务系统,但她提供完成业务系统的绝大多数开发场景,让每一位.NET 开发者都能基于DncZeus快速开发出交互、体验...
- 下一篇
Zabbix4.0 for PostgreSQL (上篇):基础环境的搭建部署
概述 Zabbix大家都很熟悉,一般的是使用MySQL作为存储库来使用的,而我看使用手册上是使用postgresql也是可以的,所以就做了一次基于pg的zabbix搭建测试,记录下来,分享给大家 Server端配置 配置PG环境 安装好pg,且在root和postgres下都配置好pg的环境变量,以供后续使用 在hba控制文件中直接加入这一行 host zabbix zabbix 192.168.0.0/24 trust host all all 127.0.0.1/32 md5 配置apache 创建user [root@Zabbix_GW_TEST opt]# adduser apache 准备好安装包并解压 [root@Zabbix_GW_TEST opt]# ls httpd-2.4.37.tar.gz httpd-2.4.37.tar.gz [root@Zabbix_GW_TEST opt]# tar -xvzf httpd-2.4.37.tar.gz 编译安装 执行编译命令 [root@Zabbix_GW_TEST httpd-2.4.37]# ./configure --...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Hadoop3单机部署,实现最简伪集群
- MySQL8.0.19开启GTID主从同步CentOS8
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS关闭SELinux安全模块
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS8安装Docker,最新的服务器搭配容器使用
- SpringBoot2配置默认Tomcat设置,开启更多高级功能