python当中的生成器
最近身边的朋友都在问我迭代器是什么回事,经常跟大家一起讨论python的迭代器,一点点的我觉着自己有了更深一层的理解。我写下这篇文章,希望能对懵懵懂懂的好伙伴有些帮助~
我也不是什么能人,难免说错一些东西,我会认真的把自己理解的说明白,欢迎各路大神批评指正。
生成器是什么??哇!不到哇~~~(眩晕持续中。。。)
生成器: 生成器是一类特殊的迭代器。
他是python提供给我们的一个功能,提供给我们快速简洁的编写迭代器的功能。
当我们需要编写一个迭代器的时候,发现迭代器很麻烦,我们需要写__next__和__iter__两个方法:
__iter__方法负责返回一个迭代器(在迭代器种返回自己,在可迭代对象中返回帮助自己迭代的迭代器)
__next__方法做两件事:
· 1 如果当前要获取的元素没有超出界限,就返回当前元素,然后自己指向为下一个元素等待返回;
2 如果上次反回了最后一个元素,这一次再调用next的时候已经没有元素了,就抛出StopIteration异常。
这两个方法中与业务逻辑相关的在next里面,而且next里面抛出异常也与我们想要迭代的元素没有关系,我们写一个迭代器实际上是很麻烦的。
在这种情况下,python提供给我们生成器的功能,通过实现一个生成器,我们只需要编写和业务逻辑有关的返回数据部分的代码,而next方法、iter方法和越界抛出异常全都由python帮助我们进行封装,不用我们操心了。这就是生成器!
迭代器又是啥啊!!我去(- 。 -) 好委屈。 迭代器呢,我之前发过一篇博文,里面详细的分享了我对迭代器的理解。欢迎伙伴们参考~~ 也可以看其他大神的博文哦~一定要搞明白 迭代器是什么否则,生成器也搞不懂的呢!
OK!!下面我和大家来探讨一下生成器的实现~~~
生成器的实现:
生成器有两种编写方法:
1 ( ) 括号内 放入列表推倒表达式 返回一个生成器对象
2 yield 关键字函数
这两种方法怎么用呢!! 我们跟大家分享一下 嘻嘻~ 大家要认真读注释哦
1 ( ) 括号内 放入列表推倒表达式 返回一个生成器对象
# 1 ( 列表推导式 ) #生成前十个偶数的列表 list = [ x*2 for x in range(11) ] print(list)#生成前十偶数的生成器 oddIterator=( x*2 for x in range(11)) print(type(oddIterator)) for num in oddIterator:print(num,end=" ")
从代码种我们可以看出,普通的列表推导式,放到括号当中,接收的对象是一个生成器对象。 它也是一个迭代器对象,可以放到for循环当中操作, 也可以用next方法一个一个取出元素,还能看到当越界的时候抛出了StopIteration的异常 这些复杂的东西都被python帮我们封装了,不需要我们自己操心去处理了。 2 yield 关键字函数 这个概念有点头痛,这什么是yield关键字函数呢? 不知道呀~ 请跟我一起理解:假如我们想写一个函数,这个函数的功能是:把传入参数n以内的偶数能给print出来。我们需要用到循环,设置一个临时变量i 从0自增2到n为止,每一次我们都print(i),这样我们就能在console中得到n以内的全部偶数。 现在我们更改需求,如果想获取n以内的偶数的生成器,我们把之前的print(i) 改成yield i ,这样就实现了这样功能的生成器。 先看一段代码!
# yield关键字函数#这个函数的功能是输出了0到n的所有偶数 def odd(n):for i in range(0,n+1,2):print(i) odd(10)#现在 我们把这个方法改成yield关键字函数的生成器 # 一个n以内偶数的生成器 def odd(n):for i in range(0,n+1,2):yield i #用gen10获取一个生成器的对象 gen10 = odd(10) # 把生成器对象放入for循环当中使用 for i in gen10:print(i,end=" ")
从代码种我们可以看出,把我们平时想要得到的数据 用yield关键字声明一下,就可以得到生成器了。python看到yield会把这个函数帮助我们继续封装,加上next方法和iter方法,并且看到越界后会帮助我们抛出异常。这些复杂的与业务逻辑无关的已经无需我们编程者来操心了,python帮助我们完成了。
现在说一下yield i 这句话到底发生了什么: 首先获得了一个迭代器对象gen = odd(20) 当函数执行到yield i 的时候 实际上函数会把i的数值抛出来,我们调用next(gen)的时候获取了yield 后面的值,然后函数就会暂停,等待下一次再调用next(gen)的时候,函数从yield继续向下执行,直到遇到yield的时候又返回了i的值,然后函数再暂停,等待下一次唤醒。 这个循环一直做,到函数结束的时候,python帮助咱们抛出了异常。 yield关键字函数的扩展: 返回值:果我们的生成器yield关键字函数当中,结束时候自己设置了返回值,这个返回值会被抛出的异常接收,存到了异常对象的value属性里面。 两种唤醒方式: 1 next(gen) 之前讨论过,调用next后,函数从上一次抛出一个数据暂停之后继续执行,直到遇到yield时候抛出来i返回给next函数再暂停,等待下一次唤醒。 2 gen.send( mess ) 这个方法也能够唤醒生成器函数,并且得到新的yield抛出数据,不同点是: 如果我们 把上面的yield抛出改成 msg = yield i , 那么我们用send传入的mess将会在唤醒的时候被msg接收到。如果我们用next方法唤醒,则msg接收到None。 很晕是不是! 我们上一段代码理解一下:
1 # yield关键字函数 2 #yield关键字函数的生成器 3 # 一个n以内偶数的生成器 4 def odd(n): 5 for i in range(0,n+1,2): 6 ''' 7 代码的执行从右向左,当遇到yield的时候,会把i抛出给next的调用返回,然后函数停在这里 8 下一次外面调用next或者send方法唤醒的时候,msg = 开始执行,上一次停在了yield i 这里,左边还没执行 9 然后再碰到yield i 的时候把i抛出来再暂停。。。。。。 10 ''' 11 msg = yield i 12 ''' 13 当函数执行结束的时候python认为迭代器结束了,帮我们抛出异常,返回值会被异常对象接收存在了value属性里面 14 ''' 15 return "哈哈哈" 16 #用gen获取一个生成器的对象 17 gen = odd(5) 18 19 #生成器也是迭代器,用next方法唤醒yield暂停,继续向下执行 20 print( next(gen) )#0 21 print( next(gen) )#2 22 print( gen.send("传入数据") )#传入数据 4 这个时候 在函数里面会打印出来传入的 “传入数据”, 并返回了下一次的i 也就是4 然后暂停 23 24 #这时候不论next还是send,迭代器都已经结束了 python会帮我们抛出异常,函数的返回值会被异常对象接收存在value属性里 25 try : 26 print( next(gen) ) 27 except StopIteration as e : 28 print(e.value) #会打印出 哈哈哈, 也就是odd函数的返回值
其实到这里 知识点就已经全部结束了。 我们再来总结一下:
生成器有两种实现方式:
1 () 括号内 放入 列表生成式
2 yield 关键字函数:正常写一个业务逻辑函数,把想迭代的数据用yield关键字声明。函数执行到yield关键字会把后面的数值抛出去,然后暂停,等待下一次唤醒。
两种唤醒方式: gen = 生成器函数() 我们拿到一个生成器对象gen
1 next(gen) 能够唤醒上一次暂停,函数会从上一次抛出数之后继续执行到再次遇见yield i 把i抛回来 后再暂停
2 gen.send(mess) 唤醒上一次暂停,并且把mess传入给接收yield 的变量,让我年后函数继续执行遇到 msg = yield i 的时候把i抛出来返回,再暂停。
生成器实质: 它是python提供给我们快速写一个迭代器的功能。我们只关心业务逻辑,把功能实现了,至于迭代器内部的iter方法和next方法已经不用我们操心了,迭代过后的抛出异常也为我们封装好好了。
因为它会被封装成迭代器,所以我们可以把生成器对象放入for in 循环中,也可以用next() 方法去获取元素!!
OK啦!! 这些知识点晦涩难懂,如果读不懂的伙伴们,希望你们认真学习一些迭代器的知识,这样才能看懂生成器哦~~可以参考我之前的博文,也可以参考其他大神的博文哦~
谢谢观赏,希望对大家有帮助!么么哒~
嘻嘻
转载于:https://www.cnblogs.com/Lin-Yi/p/7298136.html
python当中的生成器相关推荐
- python迭代器与生成器答案_史上最全 Python 迭代器与生成器
原标题:史上最全 Python 迭代器与生成器 作者:浪子燕青 链接:http://www.langzi.fun/迭代器与生成器.html 迭代器与可迭代对象 概念 迭代器:是访问数据集合内元素的一种 ...
- 五分钟学会python函数_五分钟带你搞懂python 迭代器与生成器
前言 大家周末好,今天给大家带来的是Python当中生成器和迭代器的使用. 我当初第一次学到迭代器和生成器的时候,并没有太在意,只是觉得这是一种新的获取数据的方法.对于获取数据的方法而言,我们会一种就 ...
- Python迭代器和生成器详解(包括yield详解)
文章目录 一.迭代器 1. 可迭代对象(Iterable) 2. 迭代器对象(Iterator) 3. for 循环原理 4. 迭代器的优缺点 二.生成器 1. yield 原理 2. yield 和 ...
- python 列表生成器放while_史上最全 Python 迭代器与生成器
原标题:史上最全 Python 迭代器与生成器 转自:浪子燕青 http://www.langzi.fun/迭代器与生成器.html 概念 迭代器:是访问数据集合内元素的一种方式,一般用来遍历数据,但 ...
- python基础(迭代器,生成器,装饰器)
python: 生成器: 因为当列表元素达到一定上限,列表会占很大内存空间来存储,所以列表是受到内存限制的来适当使用. 生成器可以按照一个算法,循环推导出元素,就不用一次生成整个列表,而通过生成器(g ...
- 简单介绍python迭代器和生成器
这篇文章主要介绍了Python中的迭代器和生成器,涉及到Python中很多重要的特性,需要的朋友可以参考下,希望能够给你带来帮助 python迭代器和生成器 1.迭代器 这里用字典示例 while T ...
- python编程有什么用处-python中的生成器是什么?生成器有什么用处?
在以下的文章之中我们来了解一下什么是python中生成器.了解一下python生成器是什么,以及生成器在python编程之中能起到什么样的作用. python生成器是什么? 通过列表生成式,我们可以直 ...
- python生成器和迭代器作用_浅谈Python中的生成器和迭代器
迭代器 迭代器协议 对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么返回一个异常来终止本次迭代.(只能往前走,不能往后退!) 迭代器对象 遵循了(实现了)迭代器协议的对象.(对象内 ...
- python的 是什么-python中的生成器是什么?生成器有什么用处?
在以下的文章之中我们来了解一下什么是python中生成器.了解一下python生成器是什么,以及生成器在python编程之中能起到什么样的作用. python生成器是什么? 通过列表生成式,我们可以直 ...
最新文章
- python【数据结构与算法】动态规划详解从背包到最长公共子序列(看不懂你来打我)
- 为html.EditorFor添加样式
- zookeeper下载地址及常见配置项
- 特斯拉亚洲最大超级充电站正式运营,可同时提供20辆车的快充服务
- MFC工作笔记0001---认识MFC
- SpringBoot启动错误 If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
- InstallAnywhere制作出来的安装包在64位机上无法卸载
- Java:中的String,StringBuilder,StringBuffer三者的区别
- openwrt 添加luci选项
- JavaSE复习_6 枚举类
- 互联网架构介绍 --from 光荣之路
- Charles 使用教程
- Mac OS 如何批量转换图片格式
- 技嘉主板BIOS修改风扇转速设置详细教程
- ubuntu设置桌面和锁屏背景
- SpringBoot 项目(若依脚手架)2
- oeasy教您玩转vim - 2 - # 使用帮助
- 蒸鱼的七�秘密八�做法 【精美�文】
- 带你玩转Visual Studio——Property Manager的配制
- Linux m4a转mp3