开发者社区> yunqi20191113> 正文

成为Python大牛必须要掌握的高端语法——yield

简介:
+关注继续查看

1. 什么是yield

在介绍yield语法之前,首先要向大家说明Python中的迭代(iteration)、可迭代(iterable)、迭代器(iterator)以及生成器(Generator)的概念:

迭代是一种对数据的操作,例如针对一个list逐一获取其中的元素的过程就叫做迭代。而可迭代是对象的一种特性,迭代操作只能针对拥有可迭代特性的对象进行,常见的可迭代对象包括数组、元组、字典等数据集合,下面代码给大家演示了一个基本的迭代过程:

迭代器也是一种可迭代对象,与普通的可迭代对象的区别在于,迭代器内部实现了next函数用来生成每次迭代循环需要返回的元素。而最后的生成器则又是一种特殊的迭代器,具体体现上就是使用yield语法的函数,讲到这里就提到了yield语法,总的来说yield就是用来产生一个生成器的语法,例如将上述的迭代过程修改为生成器方式可以这样写:

1240

迭代器也是一种可迭代对象,与普通的可迭代对象的区别在于,迭代器内部实现了next函数用来生成每次迭代循环需要返回的元素。而最后的生成器则又是一种特殊的迭代器,具体体现上就是使用yield语法的函数,讲到这里就提到了yield语法,总的来说yield就是用来产生一个生成器的语法,例如将上述的迭代过程修改为生成器方式可以这样写:

1240

上述代码的my_generator()即返回了一个生成器对象,每次循环时执行到yield处即返回当时的index的值,到下一次循环时将从上次返回的yield处继续执行,直到index的值不满足小于5的条件时结束整个函数,此时也结束了对这个生成器的迭代过程。

这四者之间的关系可能会稍微有些混乱,再给大家简单的总结一下:生成器是一种特殊的迭代器,而迭代器又是一种特殊的可迭代对象,可迭代对象就是可以执行迭代操作也就是可以通过for循环来遍历的对象。

本文福利:私信小编【PDF】可获取小编精心整理的电子书一套

2. 为什么要使用yield

看了上述两个迭代过程,大家可能有些疑问,使用yield改造成生成器方式的代码看起来比简单的迭代一个列表的方式要复杂许多,那么这样写有什么优势呢?

首先,使用yield语法的生成器最主要的一个优势就是极其省内存。例如上述两个迭代过程,同样是遍历输出0-4这几个元素,使用列表的方式需要构建出一个长度为5的数组并存储在内存中,而使用生成器的方式只需要一个index变量即可实现,这还是迭代元素较少的情况下,如果迭代的是100万甚至1000万个元素时,列表的方式就需要构建一个长度为100万或者1000万的数组,这时对于内存的使用就是非常大的负担了,而使用生成器的方式,无论是迭代100万还是1000万个元素,依然只需要一个index变量即可实现。

并且生成器的方式是即用即计算的,即迭代到对应的元素时,这个元素才相应的计算生成出来,而列表的方式需要在迭代开始前就构建出整个迭代数组,这在某些情况下可以极大地节省计算时间。例如下面这段代码:

1240

.在学习中有迷茫不知如何学习的朋友小编推荐一个学Python的学习q u n   227  -435-  450可以来了解一起进步一起学习!免费分享视频资料

这段代码中,实际的迭代过程只进行到第10个元素即退出了整个循环,但是在迭代开始前,依然要计算1000万次来生成迭代列表,这就造成了大量的计算和内存资源。而如果通过生成器重写该迭代过程的话:

1240

生成器在迭代开始前并不会计算出所有需要迭代的值,只有用到时才会计算相应的值并返回,因此上述代码的index将只会计算到10即结束了整个迭代过程,避免了计算和内存资源的浪费。

3. yield语法示例1:DIY一个range函数

Python自带的range函数可以产生一个可迭代对象,常用于for循环中,在Python 2中range函数生成的是一个列表,而在Python 3中range函数生成的是一个生成器。现在让我们来通过yield语法DIY一个自己的range生成器吧!

我们首先构造一个返回给定范围数组的函数:

1240

这个函数接受两个int类型的参数,分别为数组的开始和结束,每个数之间间隔为1,我们还可以通过增加一个参数来指定两个数之间的间隔,实现函数更高的灵活性:

1240

我们先来运行测试一下这个range函数:

1240

上述代码的输出结果如下:

2

4

6

输出结果符合我们的预期,现在通过yield语法来将我们自己DIY的range函数改造成一个生成器:

1240

改造起来也非常简单,首先将定义的用来存储迭代元素的列表删除,然后将原来添加元素到列表中的代码改造成yield start即可,这样我们就自己DIY了一个简易的、基于生成器实现的range函数。

4. yield语法示例2:读取文件--《告白气球》

生成器除了可以用于计算生成数字元素外,在IO读取方面也能起到很大作用,例如在读取一个超大文件,或者查询某个返回结果超多的数据库时,使用通过yield语法构造的生成器来完成读取操作可以很大程度上降低程序对于内存的占用。

例如我们有一个名为my_file.txt的文件,里面存储了周董的《告白气球》的歌词,现在我们可以通过yield语法来构造一个生成器用于一行一行的读取每一句歌词:

1240

这里使用with语法来读取文件,这是Python 3推荐的方式。file.readline()函数每次返回一行内容,由于返回的内容带有每行结尾的换行符,因此通过line.strip(‘ ’)将换行符过滤掉。每次通过yield返回一行内容之后,再次通过file.readline()函数获取下一行内容,直到整个文件被完全迭代。

让我们来运行测试一下这个按行读取文件内容的生成器:

1240

上述代码的输出结果如下:

塞纳河畔 左岸的咖啡

我手一杯 品尝你的美

留下唇印 的嘴

……

《告白气球》的歌词就一行一行的输出到屏幕上了,由于歌词行数过多,因此这边只复制出前三行给大家演示结果。

5. yield语法示例3:斐波那契数列

斐波那契数列是一道经典的算法题,也是程序员面试时经常会被问到的一道题。斐波那契数列的就是一个形如1, 1, 2, 3, 5, 8, ……的数列,从第三项开始,每一项都等于前两项之和。使用Python来实现一个计算斐波那契数列的典型函数如下:

1240

这个函数通过一个名为fib_list的数组存储生成的前n个斐波那契数,最后一次性返回整个数组。其中a, b = b, a + b是Python的一个特色用法,用于快速交换两个数,相当于:

1240

参考之前DIY的range函数的写法,将这个计算斐波那契数列的函数通过yield语法修改为生成器:

1240

让我们来测试运行一下这个通过yield语法实现的斐波那契数列生成器:

1240

对应的输出结果为:

1

1

2

3

5

可以看到,从第三项开始的每一项都是前两项的和,这样的输出结果就是我们要的斐波那契数列。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
13950 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
33614 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
18994 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
25239 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
20693 0
阿里云服务器ECS远程登录用户名密码查询方法
阿里云服务器ECS远程连接登录输入用户名和密码,阿里云没有默认密码,如果购买时没设置需要先重置实例密码,Windows用户名是administrator,Linux账号是root,阿小云来详细说下阿里云服务器远程登录连接用户名和密码查询方法
21686 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
19219 0
+关注
yunqi20191113
自己建了Python学习交流裙 227 435 450你如果学习没有用学习交流的地方可以进来一起学习交流
66
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载