当前位置: 首页 > news >正文

Python中Generators教程

要想创建一个iterator,必须实现一个有__iter__()和__next__()方法的类,类要能够跟踪内部状态并且在没有元素返回的时候引发StopIteration异常.

这个过程很繁琐而且违反直觉.Generator能够解决这个问题.

python generator是一个简单的创建iterator的途径.前面讲的那些繁琐的步骤都可以被generator自动完成.

简单来说,generator是一个能够返回迭代器对象的函数.

怎样创建一个python generator?

就像创建一个函数一样简单,只不过不使用return 声明,而是使用yield声明.

如果一个函数至少包含一个yield声明(当然它也可以包含其他yield或return),那么它就是一个generator. 

yield和return都会让函数返回一些东西,区别在于,return声明彻底结束一个函数,而yield声明是暂停函数,保存它的所有状态,并且后续被调用后会继续执行.

generator函数和普通函数的区别

  • generator函数包含一个以上的yield声明
  • generator函数被调用的时候,会返回一个iterator对象,但是函数并不会立即开始执行
  • __iter__()和__next__()方法被自动实现,所以可以使用next()函数对返回的此iterator对象进行迭代
  • 一旦一个generator 执行到yield语句,generator函数暂停,程序控制流被转移到调用方
  • 在对generator的连续调用之间,generator的本地变量和状态会被保存
  • 最终,generator函数终止,再调用generator会引发StopIteration异常

下面这个例子说明上述全部要点,我们有一个名为my_gen()的函数,它带有一些yield声明.

# A simple generator function  
def my_gen():  n = 1  print('This is printed first')  # Generator function contains yield statements  yield n  n += 1  print('This is printed second')  yield n  n += 1  print('This is printed at last')  yield n  

有趣的是,在这个例子里变量n在每次调用之间都被记住了。和一般函数不同的是,在函数yield之后本地变量没有被销毁,而且,generator对象只能被这样迭代一次。

要想重复上面的过程,需要类似 a = my_gen() 这样创建另一个generator对象,并对其使用next方法迭代。


注意

:我们可以对generator对象直接使用for循环。

这是因为一个for循环接收一个iterator对象,且使用next()函数迭代它,当遇到StopIteration异常的时候自动停止。

# A simple generator function  
def my_gen():  n = 1  print('This is printed first')  # Generator function contains yield statements  yield n  n += 1  print('This is printed second')  yield n  n += 1  print('This is printed at last')  yield n  # Using for loop  # Output:   
# This is printed first  
# 1  
# This is printed second  
# 2  
# This is printed at last  
# 3  for item in my_gen():  print(item) 

有循环的python generator

上面的例子没有实际的应用意义,我们只是为了探究背后原理。

通常来说,generator都是和循环结合实现的,且这个循环带有一个终止条件。

我们来看一个reverse一个字符串的例子

def rev_str(my_str):  length = len(my_str)  for i in range(length - 1,-1,-1):  yield my_str[i]  # For loop to reverse the string  
# Output:  
# o  
# l  
# l  
# e  
# h  
for char in rev_str("hello"):  print(char)  

我们在for循环里面使用range()函数来获取反向顺序的index。

generator除了可以应用于string,还可以应用于其它类型的iterator,例如list,tuple等。

python generator 表达式

使用generator表达式可以很容易地创建简单的generator。

就像lambda函数可以创建匿名函数一样,generator函数创建一个匿名generator函数。

generator表达式的语法类似于python的list comprehension,只是方括号被替换为了圆括号而已。

list comprehension和generator表达式的主要区别在于,前者产生全部的list,后者每次仅产生一项。

它们有些懒惰,仅在接到请求的时候才会产生输出。因此,generator表达式比list comprehension更加节省内存。

# Initialize the list  
my_list = [1, 3, 6, 10]  # square each term using list comprehension  
# Output: [1, 9, 36, 100]  
[x**2 for x in my_list]  # same thing can be done using generator expression  
# Output: <generator object <genexpr> at 0x0000000002EBDAF8>  
(x**2 for x in my_list)  

上面的例子中,generator表达式没有立即产生需要的结果,而是在需要产生item的时候返回一个generator对象。

# Intialize the list  
my_list = [1, 3, 6, 10]  a = (x**2 for x in my_list)  
# Output: 1  
print(next(a))  # Output: 9  
print(next(a))  # Output: 36  
print(next(a))  # Output: 100  
print(next(a))  # Output: StopIteration  
next(a)  

generator表达式可以在函数内部使用。当这样使用的时候,圆括号可以丢弃。

python里为什么要使用generator?

1.容易实现

相对于iterator类来说,generator的实现清晰、简洁。下面是用iterator实现一个2的指数函数

class PowTwo:  def __init__(self, max = 0):  self.max = max  def __iter__(self):  self.n = 0  return self  def __next__(self):  if self.n > self.max:  raise StopIteration  result = 2 ** self.n  self.n += 1  return result  

generator这样实现

def PowTwoGen(max = 0):  n = 0  while n < max:  yield 2 ** n  n += 1  

因为generator自动跟踪实现细节,因此更加清晰、简洁。

2.节省内存

一个函数返回一个序列(sequence)的时候,会在内存里面把这个序列构建好再返回。如果这个序列包含很多数据的话,就过犹不及了。

而如果序列是以generator方式实现的,就是内存友好的,因为他每次只产生一个item。

3.代表无限的stream

generator是一个很棒的表示无限数据流的工具。无限数据流不能被保存在内存里面,并且因为generator每次产生一个item,它就可以表示无限数据流。

下面的代码可以产生所有的奇数

def all_even():  n = 0  while True:  yield n  n += 2  

4.generator流水线(pipeline)

generator可以对一系列操作执行流水线操作。

假设我们有一个快餐连锁店的日志。日志的第四列是每小时售出的披萨数量,我们想对近5年的这一数据进行求和。

假设所有数据都是字符,不可用的数据都以"N/A"表示,使用generator可以这样实现

with open('sells.log') as file:  pizza_col = (line[3] for line in file)  per_hour = (int(x) for x in pizza_col if x != 'N/A')  print("Total pizzas sold = ",sum(per_hour))  

这个流水线既高效又易读,并且看起来很酷!:)

相关文章:

Python中Generators教程

要想创建一个iterator&#xff0c;必须实现一个有__iter__()和__next__()方法的类&#xff0c;类要能够跟踪内部状态并且在没有元素返回的时候引发StopIteration异常. 这个过程很繁琐而且违反直觉.Generator能够解决这个问题. python generator是一个简单的创建iterator的途径…...

数据结构与算法基础-学习-10-线性表之栈的清理、销毁、压栈、弹栈

一、函数实现1、ClearSqStack&#xff08;1&#xff09;用途清理栈的空间。只需要栈顶指针和栈底指针相等&#xff0c;就说明栈已经清空&#xff0c;后续新入栈的数据可以直接覆盖&#xff0c;不用实际清理数据&#xff0c;提升了清理效率。&#xff08;2&#xff09;源码Statu…...

Leetcode 每日一题 1234. 替换子串得到平衡字符串

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…...

【MYSQL中级篇】数据库数据查询学习

&#x1f341;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; 相关文章 文章名文章地址【MYSQL初级篇】入门…...

华为OD机试真题JAVA实现【火星文计算】真题+解题思路+代码(20222023)

🔥系列专栏 华为OD机试(JAVA)真题目录汇总华为OD机试(Python)真题目录汇总华为OD机试(C++)真题目录汇总华为OD机试(JavaScript)真题目录汇总文章目录 🔥系列专栏题目输入输出描述示例一输入输出说明解题思路核心知识点Code运行结果版...

Linux基础知识

♥️作者&#xff1a;小刘在C站 ♥️个人主页&#xff1a;小刘主页 ♥️每天分享云计算网络运维课堂笔记&#xff0c;努力不一定有收获&#xff0c;但一定会有收获加油&#xff01;一起努力&#xff0c;共赴美好人生&#xff01; ♥️夕阳下&#xff0c;是最美的绽放&#xff0…...

Linux 游戏性能谁的 更优秀X.Org还是Wayland!

导读X.Org 和 Wayland 是目前 Linux 平台上的两大主流显示服务器&#xff0c;那么两者在 Linux 游戏性能上谁更优秀呢&#xff1f;国外科技媒体 Phoronix 在 Ubuntu 22.10 上对其进行了多款游戏的实测。评测在运行 GNOME 43.1 的 Ubuntu 22.10 上进行测试&#xff0c;在安装英伟…...

【数据结构】算法的复杂度分析:让你拥有未卜先知的能力

&#x1f451;专栏内容&#xff1a;数据结构⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;日拱一卒&#xff0c;功不唐捐 文章目录一、前言二、时间复杂度1、定义2、大O的渐进表示法3、常见的时间复杂度三、空间复杂度1、定义2、常见的空间复杂度一、前…...

Linux根文件系统移植

目录 一、根文件系统 1.1根文件系统 1.2根文件系统内容 二、根文件系统移植 2.1BusyBox 2.2BusyBox的获取 2.3BusyBox的使用 2.4make menuconfig 2.5编译和安装 2.6修改根文件系统 一、根文件系统 1.1根文件系统 根文件系统是内核启动后挂载的第一个文件系统系统引…...

Three.js 无限平面快速教程【Plane】

Three.js 提供了 Plane 概念来表示在 3d 空间中无限延伸的二维表面。 这对于光标交互很有用&#xff0c;因此你可能需要了解如何设置此平面、将其可视化并根据需要进行调整。 推荐&#xff1a;使用 NSDT场景设计器 快速搭建 3D场景。 Three.js 的 Plane 文档很好而且准确&…...

在线预览PDF文件、图片,并且预览地址不显示文件或图片的真实路径。

实现在线预览PDF文件、图片&#xff0c;并且预览地址不显示文件或图片的真实路径。1、vue使用blob流在线预览PDF、图片&#xff08;包括jpg、png等格式&#xff09;。1、按钮的方法&#xff1a;2、方法详细&#xff1a;&#xff08;此方法可以在发起请求时携带token&#xff0c…...

Allegro如何设置导入Subdrawing可自由选择目录操作指导

Allegro如何设置导入Subdrawing可自由选择目录操作指导 用Allgro做PCB设计的时候,导入Subdrawing是非常常用的功能,在导入Subdrawing的时候,通常需要把Subdrawing文件放在需要导入PCB的相同目录下,不能自由选择,如下图 但是Allegro是支持自由选择目录的,只需按照下方的步…...

SpirngMVC执行原理--自学版

DispatcherServlet表示前置控制器&#xff0c;是整个SpringMVC的控制中心&#xff0c;用户发出请求&#xff0c;DispatcherServlet接收请求并拦截请求HandlerMapper为处理器映射。DispatcherServlet调用。HandlerMapping根据请求url查找HandlerHandlerExecution表示具体的Handl…...

获取savemodel的输入输出节点

saved_model_cli show --dir savemodels --all 结果&#xff1a; MetaGraphDef with tag-set: ‘serve’ contains the following SignatureDefs: signature_def[‘translation_signature’]: The given SavedModel SignatureDef contains the following input(s): inputs[‘i…...

《Learning to Reconstruct Botanical Trees from Single Images》学习从单幅图像重建植物树

读书报告下载https://download.csdn.net/download/weixin_43042683/87448211论文原文https://dl.acm.org/doi/10.1145/3478513.3480525论文视频https://www.bilibili.com/video/BV1cb4y127Vp/?fromseopage&vd_source5212838c127b01db69dcc8b2d27ca5171引言植物存在在室外与…...

vant 4 正式发布,支持暗黑主题,那么是如何实现的呢

2022年10月25日首发于掘金&#xff0c;现在同步到公众号。11. 前言大家好&#xff0c;我是若川。我倾力持续组织了一年多源码共读&#xff0c;感兴趣的可以加我微信 lxchuan12 参与。另外&#xff0c;想学源码&#xff0c;极力推荐关注我写的专栏《学习源码整体架构系列》&…...

MySQL的复制 二

复制是MySQL的一项功能&#xff0c;使服务器能够将更改从一个实例恢复到另一个实例 主服务器&#xff08;master&#xff09;将所有数据和结构更改记录到二进制日志中。二进制日志格式是基于语句的、基于行的和混合的。 从属服务器&#xff08;slave&#xff09;从主服务器请求…...

秒杀项目之秒杀商品展示及商品秒杀

目录前言一、登录方式调整二、生成秒杀订单2.1 绑定秒杀商品2.2 查看秒杀商品2.3 订单秒杀2.3.1 移除seata相关&#xff08;方便测压&#xff09;2.3.2 生成秒杀订单2.3.3 前端页面秒杀测试注意前言 博主博客用到的资源都会同步分享到资源包中 一、登录方式调整 第1步&#xf…...

教育行业需要什么样的数字产品?

数字化转型的浪潮已经席卷了各行各业&#xff0c;不仅出现在互联网、电商、建筑等行业&#xff0c;还应用在了教育行业。数字化的教育ERP软件能够在满足学校需求的基础上&#xff0c;帮助学校完善各类工作流程&#xff0c;提高工作效率。 对于一个拥有多个校区&#xff0c;上万…...

Spring MVC

一、Spring MVC介绍 a. Spring MVC是一个Web框架 b. Spring MVC是基于Servlet API构成的 MVC 是 Model View Controller 的缩写。 MVC 是⼀种思想&#xff0c;⽽ Spring MVC 是对 MVC 思想的具体实现。 学习Spring MVC目标&#xff1a; a.连接功能&#xff1a;将用户&#xff…...

类与对象(上)

类与对象(上) 1.面向过程和面向对象初步认识 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。 C是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之间…...

正确安装 torch_geometric库

step1&#xff1a; 查看pytorchcuda 版本 torch-scatter torch-sparse torch-cluster torch-spline-conv 这些关联包要与torch版本匹配。 import torch print(torch.__version__) print(torch.cuda.is_available()) torch.version.cuda或者 pip list查看版本 step2&#xff…...

【Unity VR开发】结合VRTK4.0:自身移动(滑动)

语录&#xff1a; 依山傍水房树间&#xff0c;行也安然&#xff0c;住也安然&#xff1b; 一条耕牛半顷田&#xff0c;收也凭天&#xff0c;荒也凭天&#xff1b; 雨过天晴驾小船&#xff0c;鱼在一边&#xff0c;酒在一边&#xff1b; 夜晚妻子话灯前&#xff0c;今也谈谈…...

G1垃圾回收器详解

文章目录前言一、思考问题二、官方文档三、基本介绍四、G1的内存模型五、G1的标记过程六、G1的垃圾回收1、G1过程梳理2、Young GC3、Mixed GC4、Full GC七、参数介绍八、典型问题1、疏散失败&#xff08;Evacuation Failure&#xff09;2、大对象分配&#xff08;Humongous All…...

tws耳机哪个牌子音质好?tws耳机音质排行榜

随着蓝牙耳机市场的不断发展&#xff0c;使用蓝牙耳机的人也逐渐增多&#xff0c;近年来更是超越有线耳机成为最火爆的数码产品之一。那么&#xff0c;tws耳机哪个牌子音质好&#xff1f;下面&#xff0c;我来给大家推荐几款音质好的tws耳机&#xff0c;可以当个参考。 一、南…...

TIA博途中DB数据块清零的具体方法示例

TIA博途中DB数据块清零的具体方法示例 TIA中数据块如何实现清零? 在TIA指令集内有多个移动指令可对DB块内数据进行清零处理。对于S7-1500 CPU或ET200SP CPU来说,可使用BLKMOV、FILL以及SCL的POKE_BLK指令。但是这些指令对DB块清零时,要求DB块必需为非优化DB。 对于优化的DB…...

iptables防火墙屏蔽指定ip的端口

因为需要测试客户端程序与hadoop服务器之间正常通信需要开通的端口, 所以在hadoop各服务器上使用iptables防火墙屏蔽了测试客户端程序的ip和所有端口。然后&#xff0c;根据报错信息提示的端口号来逐步放开直到能正常通信下载文件。 在服务器端屏蔽指定ip访问所有端口 #查看…...

JavaScript Math(算数) 对象

JavaScript Math&#xff08;算数&#xff09; 对象 Math 是一个内置对象&#xff0c;它拥有一些数学常数属性和数学函数方法。Math 不是一个函数对象。 Math 用于 Number 类型。它不支持 BigInt。 描述 与其他全局对象不同的是&#xff0c;Math 不是一个构造器。Math 的所…...

超详细的JAVA高级进阶基础知识04

目录 4. 面向对象高级 - 常用的API 4.1 Arrays 工具类 4.1.1 Arrays 类介绍 4.2 冒泡排序 4.3 选择排序 4.4 二分查找 4.5 正则表达式 4.5.1 String 类中与正则有关的常见方法 4.5.2 练习 4.5.3 今日学习目标 4. 面向对象高级 - 常用的API 4.1 Arrays 工具类 4.1.1…...

Python 运算符?

什么是运算符&#xff1f; 本章节主要说明Python的运算符。举个简单的例子 4 5 9 。 例子中&#xff0c;4 和 5 被称为操作数&#xff0c; 称为运算符。 Python语言支持以下类型的运算符: 算术运算符 比较&#xff08;关系&#xff09;运算符 赋值运算符 逻辑运算符 位运算符…...

雄安网站建设推广/百度榜单

这次比赛不好。 一开始来到&#xff0c;看到第一题&#xff0c;感觉好神奇。然后&#xff0c;用草稿本划来划去&#xff0c;发现规律&#xff0c;把序列快牌&#xff0c;把越大的而且合理的数尽量丢在左子树&#xff0c;于是按照堆的性质&#xff0c;就切掉了。还感觉不对&…...

镇江本地网站/什么平台可以发广告引流

Python最大的优点之一就是语法简洁&#xff0c;好的代码就像伪代码一样&#xff0c;干净、整洁、一目了然。要写出 Pythonic&#xff08;优雅的、地道的、整洁的&#xff09;代码&#xff0c;需要多看多学大牛们写的代码&#xff0c;github 上有很多非常优秀的源代码值得阅读&a…...

wordpress指定文章p=/谷歌账号注册

1.优先使用异步消息。 上文已经说过&#xff0c;使用异步消息 Consumer 端需要实现幂等。幂等有两种方式&#xff0c;一种方式是业务逻辑保证幂等。比如接到支付成功的消息订单状态变成支付完成&#xff0c;如果当前状态是支付完成&#xff0c;则再收到一个支付成功的消息则说明…...

如何建一个免费网站/百度站长平台官网登录入口

本文参考自《剑指offer》一书&#xff0c;代码采用Java语言。题目请实现一个函数用来匹配包含.和*的正则表达式。模式中的字符.表示任意一个字符&#xff0c;而*表示它前面的字符可以出现任意次(含0次)。在本题中&#xff0c;匹配是指字符串的所有字符匹配整个模式。例如&#…...

做前端网站用什么工具/企业推广是做什么的

请问大家ndk中LOCAL_SHARED_LIBRARIES LOCAL_LDLIBS什么区别啊 我先是编译了一个.so 然后在此次编译的使用调用&#xff0c;请问用LOCAL_SHARED_LIBRARIES和LOCAL_LDLIBS什么区别啊&#xff0c;我用后者能编译通过&#xff0c;用前者不行呢&#xff0c;谢谢&#xff01;&#…...

征集二级网站建设意见 通知/线上营销推广

之前我发布过一篇对urp的内置shader lit的结构解析&#xff0c;发现自己说的也不完善&#xff0c;这次直接对源码进行一个解析&#xff0c;并提升一下自己的记忆。 如果你找不到这个shader&#xff0c;那么就有可能你不是urp渲染管线。自己搜索。 在前向渲染pass里面&#xf…...