代码流程图生成器_【进阶Python】第五讲:迭代器与生成器

3b143e5649ff76c7015dbacc622d5ea6.png

点击蓝字关注我

3b143e5649ff76c7015dbacc622d5ea6.png
迭代是Python中常用且非常强大的一个功能,它可以用于访问集合、列表、字符串、字典等数据结构的元素。我们经常使用循环和条件语句,我们也清楚哪些是可以迭代访问,但是具体它们之间有什么有什么异同之处?有哪些特点?什么是迭代器、什么是生成器、什么是可迭代对象?这些问题对于初学者而言却是很少去细致的研究,本文就来详细阐述一下它们之间的关系已经它们的特别之处。

—▼—

可迭代对象

b30e0e14a187af410da273cf6e75b368.png

在讲解迭代器和生成器之前,先介绍一下可迭代对象。

可迭代对象是Python中一个非常庞大的概念,它主要包括如下三类:

  • 迭代器

  • 序列

  • 字典

从上图可以看出不同概念之间的关系,迭代器是可迭代对象的一个子集,而生成器又是迭代器的一个子集,是一种特殊的迭代器。除了迭代器之外,Python中还有序列、字典等可迭代对象。

现在已经直观的了解了可迭代对象与迭代器、生成器之间的关系,那么用Python语言怎么表述它们的区别呢?

  • 可迭代对象需要实现__iter__方法

  • 迭代器不仅要实现__iter__方法,还需要实现__next__方法

在使用层面,可迭代对象可以通过innot in访问对象中的元素,举一个例子,

X = set([1,2,3,4,5])print(X)print(type(X))print(1 in X)print(2 not in X)for x in X:    print(x)# 输出{1, 2, 3, 4, 5}<class 'set'>TrueFalse
1
2
3
4
5

前面提到,可迭代对象实现了__iter__方法,但是它没有实现__next__,这也是判定迭代器和其他可迭代对象的关键之处,可以看一下通过next访问上述示例中可迭代对象X会报错,

next(X)# 输出TypeError: 'set' object is not an iterator

报的错误是'set' object is not an iterator,它指明了set集合是一个可迭代对象,但不是迭代器,下面就来介绍一下迭代器。

迭代器

迭代器是可迭代对象的一个子集,它是一个可以记住遍历的位置的对象,它与列表、元组、集合、字符串这些可迭代对象的区别就在于next方法的实现,其他列表、元组、集合、字符串这些可迭代对象可以很简单的转化成迭代器,通过Python内置的iter函数能够轻松把可迭代对象转化为迭代器,下面来看一个例子,

X = [1,2,3,4,5]print(type(X))Y = iter(X)print(type(Y))print(next(Y))print(next(Y))print(next(Y))# 输出<class 'list'>
<class 'list_iterator'>
1
2
3

从上述示例中我们可以看出两点:

  • 通过iter函数把list转化成了迭代器

  • 可迭代器能够记住遍历位置,能够通过next方法不断从前往后访问

除了Python内置的iter之外,还可以通过Python内置的工具包itertools创建迭代器,其中函数包括,

  • count

  • cycle

  • repeat

  • accumulate

  • chain

  • compress

  • dropwhile

  • islice

  • product

  • permutations

  • combinations

  • ……

itertools中包含很多用于创建迭代器的实用方法,如果感兴趣嗯可以访问官方文档进行详细了解。

当然,也可以自己通过实现__iter____next__方法来定义迭代器,

class Iterator(object):    def __init__(self, array):        self.x = array        self.index = 0    def __iter__(self):        return self    def __next__(self):        if self.index             value = self.x[self.index]            self.index += 1        else:            raise StopIteration        return valueit = Iterator([1,2,3,4,5])print(type(it))for i in it:    print(i)# 输出<class '__main__.Iterator'>
1
2
3
4
5

生成器

从文章开头的流程图可以直观的看出,生成器是迭代器的子集,换句话说,生成器一定是迭代器,但是迭代器不全是生成器对象。

提及生成器就不得不提及一个Python中的关键字yiled,在Python中一个函数可以用yiled替代return返回值,这样的话这个函数就变成了一个生成器对象,举个例子对比一下,

def generator(array):    for i in array:        return igen = generator([1,2,3,4,5])print(type(gen))# 输出<class 'int'>

这是我们常见的return返回方式,这样的话generator函数获取的是一个int型对象,下面看一下换成yield关键字,

def generator(array):    for i in array:        yield(i)gen = generator([1,2,3,4,5])print(type(gen))# 输出<class 'generator'>

这样的话获取的是一个生成器generator,除了yield之外,在Python3.3之后还加入了yield from获取生成器,允许一个生成器将其部分操作委派给另一个生成器,使得生成器的用法变得更加简洁,yield from后面需要加上可迭代对象,这样可以把可迭代对象变成生成器,当然,这里的可迭代对象不仅包含列表、元组,还包含迭代器、生成器。yield from相对于yield的有几个主要优点:

  • 代码更加简洁

  • 可以用于生成器嵌套

  • 易于异常处理

下面就从简洁代码方面举个例子说明一下,

def generator(array):    for sub_array in array:        yield from sub_arraygen = generator([(1,2,3), (4,5,6,7)])# 输出1234567

当我们需要访问多层/多维可迭代对象时,我们就不需要逐层的去用for … in …去访问,可以简单的通过yiled from把生成器委派给子生成器,除此之外还可以通过生成器表达式的方法得到生成式,后面会介绍。

print(next(gen))print(next(gen))# 输出12

通过上面示例可以看出,生成器可以像迭代器那样使用iter和next方法。

读到这里可以会有疑惑,从这个示例看来生成器和迭代器并没有什么区别啊?为什么生成器还可以称得上是Python中的一大亮点?

首先它对比于迭代器在编码方面更加简洁,这是显而易见的,其次生成器运行速度更快,最后一点,也是需要着重说明的一点:节省内存。

也许在一些理论性实验、学术论文阶段可以不考虑这些工程化的问题,但是在公司做项目时,内存和资源占用是无法逃避的问题 。如果我们使用其他可迭代对象处理庞大的数据时,当创建或者返回值时会申请用于存储整个可迭代对象的内存,显然这是非常浪费的,因为有的元素当前我们用不到,也不会去访问,但它却一直占用这内存。这时候就体现了生成器的优点,它不是一次性把所有的结果都返回,而是当我们每读取一次,它会返回一个结果,当我们不读取时,它就是一个生成器表达式,几乎不占用内存。

生成器表达式

首先来看一个对比示例,
X = [1, 2, 3, 4, 5]it = [i for i in X]gen = (i for i in X)print(type(X))print(type(it))print(type(gen))# 输出<class 'list'>
<class 'list'>
<class 'generator'>
首先说一下it = [i for i in X],这种用法叫做列表生成式,在很多编程规范中非常推崇的一种替代for循环的方式,仔细看一下代码会发现,it = [i for i in X]gen = (i for i in X)的区别非常小,只是一个用了中括号,一个用了小括号,但是它们的区别缺失非常大的,使用中括号的叫做列表生成式,获得的返回值是一个列表,而使用小括号叫做生成器表达式,获得的返回结果是一个生成器,这也是前面提到的,除了使用yield和yield from两个关键字外还可以使用生成器表达式获得生成器。

END

c6443642dd5f53d55426d5e855582ae7.png4a064e6eb62f9d0317125eb12bb38016.png有趣的灵魂在等你

长按扫码可关注 

相关文章【进阶Python】第一讲:开篇【进阶Python】第二讲:装饰器【进阶Python】第三讲:类的特殊方法(上篇)【进阶Python】第四讲:类的特殊方法(下篇)文章好看就点这里a3afca7a086dc036bfd82630ea12e3e0.gif

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

生成最简单的验证码图片的Java代码

后端代码&#xff1a; package priv.lwx.servlet.sl.web; /*** description** author liaowenxiong* date 2022/3/25 09:56*/import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.…

cognito_将Amazon Cognito与单页面应用程序(Vue.js)集成

cognito在本文中&#xff0c;我们将研究使用OAuth协议通过Amazon Cognito对单页应用程序&#xff08;使用Vue.js构建&#xff09;进行身份验证。 在上一篇文章中&#xff0c;我们将服务器端应用程序与Amazon Cognito集成在一起。 搭建单页应用程序 我们将使用vue-cli创建一个空…

段描述符表(GDT+LDT)的有感

【0】写在前面 要知道&#xff0c;在汇编中&#xff0c;代码的装入顺序决定了在内存中的地址位置。所有的代码或者数据都在硬盘上&#xff0c;当调试或者启动的时候&#xff0c;加载到内存&#xff1b;当需要对数据进行处理的时候&#xff0c;我们通过将数据从内存载入到regis…

地理信息系统概论_地理信息系统概论黄杏元第3版配套练习题库——才聪学习网...

黄杏元《地理信息系统概论》(第3版)配套题库【考研真题精选&#xff0b;章节题库】一、选择题1完整的GIS主要由四个部分构成&#xff0c;即计算机硬件系统、计算机软件系统、(  )和系统管理操作人员。[杭州师范大学2018年研]A&#xff0e;网络B&#xff0e;用户C&#xff0e;…

PO/BO/VO/DTO/POJO/DAO/DO

文章目录DO&#xff08;Domain Object&#xff09;DO&#xff08;Data Object&#xff09;POVOBODTOPOJODAOJavaBeanEJBEntity应用程序的分层设计MVC业务分层阿里开发手册关于POJO类的命名规范总结参考文章DO&#xff08;Domain Object&#xff09; Domain Object&#xff0c;…

openshift_OpenShift Origin中的Kubernetes Spark运算符(第1部分)

openshift本系列有关Radanalytics.io的Kubernetes Spark运算符 OpenShift起源 。 它是一个开源的运营商来管理 Apache Spark集群和应用程序。 为了在OpenShift Origin上部署操作员&#xff0c;第一次需要为其克隆GitHub存储库&#xff1a; git clone https://github.com/rad…

小程序二级页面tabbar_小程序页面推广踩坑记

前几天&#xff0c;团队里有个小伙伴遇到一个问题&#xff0c;卡壳了大半天。我觉得这个例子值得拿出来分享给大家。希望大家以后遇到类似的问题能顺利绕过这种坑。业务场景很常见&#xff0c;就是为了配合小程序中特定页面的推广&#xff0c;区分推广渠道和人员&#xff0c;逐…

转移指令jmp和跳转指令call

【-1】写在前面 以下内容文字描述来自于 王爽老师的《汇编语言》教材&#xff0c;建议大家都买一本&#xff0c;哈哈。不是我打广告&#xff0c;确实人家写的好&#xff0c;应该支持。我只是附上了自己的图片和理解而已。 【0】先上干货 只修改ip&#xff0c;称为段内转移&a…

jmeter负载测试测试_使用Apache JMeter负载测试Web应用程序

jmeter负载测试测试Apache JMeter是用于模拟Web应用程序上的用户负载以测试性能的出色工具。 您可以通过指定用户数量和请求间隔来轻松地构建测试计划&#xff0c;然后JMeter将为每个用户生成一个线程并访问您的Web应用程序。 在测试结束时&#xff0c;您将获得一份性能摘要报告…

Windows下安装Nutch

Nutch安装 一、需求部份 a) Nutch是Java开发的所以需要下载Java JDK 下载地址http://java.sun.com/javase/downloads/index.jsp b) Nutch的演示搜索页面是Jsp的需要Tomcat做服务器 下载地址&#xff1a;http://jakarta.apache.org/tomcat/ c) Nutch的脚本都是用Linux的Shell写的…

python子进程关闭fd_gpg –passphrase-fd无法使用python 3子进程

以下脚本encrypt_me.py(modified from another post)使用gpg加密自身并以装甲形式打印出密文.但它只适用于python2.7但不适用于python3&#xff1f;你知道它在python3上运行时有什么问题吗&#xff1f;import subprocessimport shleximport osimport sysin_fd, out_fd os.pipe…

程序编码(机器级代码+汇编代码+C代码+反汇编)

【-1】相关声明 本文总结于csapp&#xff1b; 了解详情&#xff0c;或有兴趣&#xff0c;建议看原版书籍&#xff1b;【0】程序编码 GCC调用了一系列程序&#xff0c;将源代码转化成可执行代码的流程如下&#xff1a; &#xff08;1&#xff09;C预处理器扩展源代码&#xf…

angular1.2.27_Angular 8 + Spring Boot 2.2:立即构建一个CRUD应用程序!

angular1.2.27“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕&#xff1f; 尝试使用Okta API进行托管身份验证&#xff0c;授权和多因素身份验证。 如果您已经成为Java开发人员超过15年&#xff0c;那么您可能还记得何时…

ssm中怎么用location.href跳到controller层_聊聊自动驾驶中的功能开发

在知乎上看过不少大牛写的自动驾驶技术介绍文章&#xff0c;大多谈到的是AI, Deep Learning, Computer Vision等等感知(Perception)层面的。但在各个传感器(雷达、摄像头、激光雷达等)探测到目标信息及周围环境后&#xff0c;车辆该如何做出反应&#xff1f;自动驾驶的大脑该怎…

MyEclipse详细使用教程

第一部分MyEclipse的基本使用 一&#xff0e;提示&#xff1a;MyEclipse的透视图按钮&#xff1a;可以切换不同的透视图&#xff08;位于右上角&#xff09; 1.建立一个工程 ----File—new—project—选项含有Javaproject&#xff0c;webproject等等—输入工程名字如myproject&…

控制语句(if-else+循环+switch)汇编规则

【1】说说条件码 最常用的的条件码有&#xff1a; CF&#xff1a;进位标志 &#xff08;无符号溢出&#xff09;ZF&#xff1a;零标志SF&#xff1a;符号标志&#xff08;结果为负数&#xff09;OF&#xff1a;溢出标志 &#xff08;补码溢出&#xff0c; 有符号溢出&#xf…

zxing qr区域判断_如何在Java中使用Zxing和JFreeSVG创建QR Code SVG?

zxing qr区域判断在本文中&#xff0c;我们将研究如何使用Zxing QR代码生成库和JFreeSVG库在Java中创建QR Code SVG图像。 QR码生成 下面的代码使用Zxing库创建一个表示QR Code的java.awt.image.BufferedImage对象&#xff1a; public static BufferedImage getQRCode(String …

审批流_怎样让审批工作流和应用数据分离?

在企业行政管理中&#xff0c;审批是最常遇到的场景。传统管理中&#xff0c;人们会有纸张审批&#xff0c;而现在市场上已有大量的线上审批软件&#xff0c;他们帮助企业完成审批电子化&#xff0c;审批速度更快&#xff0c;信息也能留档。然而大部分审批软件都不够灵活&#…

java 反射api_反射是最重要的Java API

java 反射api前几天我在想-这是最重要的Java API。 哪种SE和EE API可以使大多数Java生态系统成为可能&#xff0c;而哪些API不能重新创建为第三方库。 正如您可能已经猜到标题一样&#xff0c;我认为它是Reflection API 。 是的&#xff0c;它不可避免地是每个项目的直接或间接…

前端校验表单项内容是否合规的JS脚本代码

用途&#xff1a;校验ip地址的格式 输入&#xff1a;strIP&#xff1a;ip地址 返回&#xff1a;如果通过验证返回true,否则返回false&#xff1b; */ function isIP(strIP) { if (isNull(strIP)) return false; var re/^(\d).(\d).(\d).(\d)$/g //匹配IP地址的正则表达式 if(r…