热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python知识点:Python生成器

生成器,是一个用来创建迭代器的工具。它简单而强大,类似写函数那样进行定义,但是需要返回数据时不是使用return,而是使用y

生成器,是一个用来创建迭代器的工具。它简单而强大,类似写函数那样进行定义,但是需要返回数据时不是使用return,而是使用yield语句。
在这里插入图片描述

生成器

生成器函数
用yield语句返回数据的“函数”,称为生成器函数。我们把上一节中自定义类LessThan改写成生成器函数:

In [30]: def lessthan(n): ...: for i in range(n-1, -1, -1): ...: yield i ...: ...:In [31]: for i in lessthan(5): ...: print(i) ...:
4
3
2
1
0
In [32]: lt = lessthan(3)## 查看生成器对象的__iter__()和__next__():
In [33]: lt.__iter__?
Signature: lt.__iter__()
Call signature: lt.__iter__(*args, **kwargs)
Type: method-wrapper
String form: <method-wrapper &#39;__iter__&#39; of generator object at 0x7fc048cb8ba0>
Docstring: Implement iter(self).In [34]: lt.__next__?
Signature: lt.__next__()
Call signature: lt.__next__(*args, **kwargs)
Type: method-wrapper
String form: <method-wrapper &#39;__next__&#39; of generator object at 0x7fc048cb8ba0>
Docstring: Implement next(self).

通过生成器改写LessThan类后&#xff0c;代码更加简洁紧凑&#xff0c;因为它自动创建了__iter__()和__next__()方法&#xff0c;通过for循环可以遍历生成器对象。

接下来我们定义一个生成器对象lt&#xff0c;对这个生成器对象调用next()&#xff0c;每一次调用它都会从上次离开的位置回复执行&#xff08;也就是记住上次执行语句时的所有数据值&#xff09;。当生成器生成了所有元素&#xff08;生成器终结&#xff09;就会引发StopIteration错误。

In [53]: lt &#61; lessthan(3)In [54]: next(lt)
Out[54]: 2In [55]: next(lt)
Out[55]: 1In [56]: next(lt)
Out[56]: 0In [57]: next(lt)
---------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-37-00f31299a3f9> in <module>
----> 1 next(lt)StopIteration:

生成器解析式
为了实现一些简单的生成器&#xff0c;我们可以不用函数的形式&#xff0c;而是用类似列表解析式的语法&#xff0c;将外层的方括号用圆括号代替即可。

生成器表达式相比完整的生成器更紧凑但较不灵活&#xff0c;相比等效的列表推导式则更为节省内存。比如下面的的代码&#xff0c;用列表表达式生成的mylist的每个元素都保存在内存中&#xff0c;而mygener每次迭代时才会产生一个元素。假设元素个数不是10&#xff0c;而是100万甚至更多&#xff0c;此时生成器的内存优势会非常明显。

In [41]: mylist &#61; [i*i for i in range(10)]In [42]: mylist
Out[42]: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]In [43]: mygener &#61; (i*i for i in range(10))In [44]: mygener

Out[44]:
生成器解析式被设计用于生成器将立即被外层函数所使用的情况&#xff0c;比如&#xff1a;

In [45]: sum(i*i for i in range(10))
Out[45]: 285

sum()括号里面的i*i for i in range(10)就是一个生成器解析式&#xff0c;避免生成一个列表而占用过多内存。

同样的&#xff0c;下面的例子中都是使用了生成器解析式&#xff1a;

xvec &#61; [10, 20, 30]
yvec &#61; [7, 5, 3]
sum(x*y for x,y in zip(xvec, yvec)) # dot productfrom math import pi, sin
sine_table &#61; {x: sin(x*pi/180) for x in range(0, 91)}unique_words &#61; set(word for line in page for word in line.split())valedictorian &#61; max((student.gpa, student.name) for student in graduates)data &#61; &#39;golf&#39;
list(data[i] for i in range(len(data)-1, -1, -1))

总结
Python提供了两种方式实现生成器&#xff1a;

&#xff08;1&#xff09;生成器函数
语法上与普通函数相似&#xff0c;用yield替代return换回值&#xff1b;自动实现迭代器协议&#xff1a;iter()方法和__next__()方法。没有值可返回时&#xff0c;引起StopInteration异常。yield语句挂起生成器函数的状态&#xff0c;以便再次迭代时从离开的状态继续执行。

&#xff08;2&#xff09;生成器解析式
类似列表解析式&#xff0c;用圆括号替换方括号&#xff0c;从而简单实现简单的生成器。

&#xff08;3&#xff09;生成器的优点
代码紧凑&#xff0c;节省内存。不像列表可以多次遍历&#xff0c;生成器只能遍历一遍。
Python学习路线图&#xff1a;&#xff08;路线&#xff09;


推荐阅读
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 也就是|小窗_卷积的特征提取与参数计算
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了卷积的特征提取与参数计算相关的知识,希望对你有一定的参考价值。Dense和Conv2D根本区别在于,Den ... [详细]
  • springmvc学习笔记(十):控制器业务方法中通过注解实现封装Javabean接收表单提交的数据
    本文介绍了在springmvc学习笔记系列的第十篇中,控制器的业务方法中如何通过注解实现封装Javabean来接收表单提交的数据。同时还讨论了当有多个注册表单且字段完全相同时,如何将其交给同一个控制器处理。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 本文介绍了一个题目的解法,通过二分答案来解决问题,但困难在于如何进行检查。文章提供了一种逃逸方式,通过移动最慢的宿管来锁门时跑到更居中的位置,从而使所有合格的寝室都居中。文章还提到可以分开判断两边的情况,并使用前缀和的方式来求出在任意时刻能够到达宿管即将锁门的寝室的人数。最后,文章提到可以改成O(n)的直接枚举来解决问题。 ... [详细]
  • 3.223.28周学习总结中的贪心作业收获及困惑
    本文是对3.223.28周学习总结中的贪心作业进行总结,作者在解题过程中参考了他人的代码,但前提是要先理解题目并有解题思路。作者分享了自己在贪心作业中的收获,同时提到了一道让他困惑的题目,即input details部分引发的疑惑。 ... [详细]
  • Ihavethefollowingonhtml我在html上有以下内容<html><head><scriptsrc..3003_Tes ... [详细]
author-avatar
LuoXR小堇_137
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有