最近身边的朋友都在问我迭代器是什么回事,经常跟大家一起讨论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当中的生成器相关推荐

  1. python迭代器与生成器答案_史上最全 Python 迭代器与生成器

    原标题:史上最全 Python 迭代器与生成器 作者:浪子燕青 链接:http://www.langzi.fun/迭代器与生成器.html 迭代器与可迭代对象 概念 迭代器:是访问数据集合内元素的一种 ...

  2. 五分钟学会python函数_五分钟带你搞懂python 迭代器与生成器

    前言 大家周末好,今天给大家带来的是Python当中生成器和迭代器的使用. 我当初第一次学到迭代器和生成器的时候,并没有太在意,只是觉得这是一种新的获取数据的方法.对于获取数据的方法而言,我们会一种就 ...

  3. Python迭代器和生成器详解(包括yield详解)

    文章目录 一.迭代器 1. 可迭代对象(Iterable) 2. 迭代器对象(Iterator) 3. for 循环原理 4. 迭代器的优缺点 二.生成器 1. yield 原理 2. yield 和 ...

  4. python 列表生成器放while_史上最全 Python 迭代器与生成器

    原标题:史上最全 Python 迭代器与生成器 转自:浪子燕青 http://www.langzi.fun/迭代器与生成器.html 概念 迭代器:是访问数据集合内元素的一种方式,一般用来遍历数据,但 ...

  5. python基础(迭代器,生成器,装饰器)

    python: 生成器: 因为当列表元素达到一定上限,列表会占很大内存空间来存储,所以列表是受到内存限制的来适当使用. 生成器可以按照一个算法,循环推导出元素,就不用一次生成整个列表,而通过生成器(g ...

  6. 简单介绍python迭代器和生成器

    这篇文章主要介绍了Python中的迭代器和生成器,涉及到Python中很多重要的特性,需要的朋友可以参考下,希望能够给你带来帮助 python迭代器和生成器 1.迭代器 这里用字典示例 while T ...

  7. python编程有什么用处-python中的生成器是什么?生成器有什么用处?

    在以下的文章之中我们来了解一下什么是python中生成器.了解一下python生成器是什么,以及生成器在python编程之中能起到什么样的作用. python生成器是什么? 通过列表生成式,我们可以直 ...

  8. python生成器和迭代器作用_浅谈Python中的生成器和迭代器

    迭代器 迭代器协议 对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么返回一个异常来终止本次迭代.(只能往前走,不能往后退!) 迭代器对象 遵循了(实现了)迭代器协议的对象.(对象内 ...

  9. python的 是什么-python中的生成器是什么?生成器有什么用处?

    在以下的文章之中我们来了解一下什么是python中生成器.了解一下python生成器是什么,以及生成器在python编程之中能起到什么样的作用. python生成器是什么? 通过列表生成式,我们可以直 ...

最新文章

  1. python【数据结构与算法】动态规划详解从背包到最长公共子序列(看不懂你来打我)
  2. 为html.EditorFor添加样式
  3. zookeeper下载地址及常见配置项
  4. 特斯拉亚洲最大超级充电站正式运营,可同时提供20辆车的快充服务
  5. MFC工作笔记0001---认识MFC
  6. SpringBoot启动错误 If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
  7. InstallAnywhere制作出来的安装包在64位机上无法卸载
  8. Java:中的String,StringBuilder,StringBuffer三者的区别
  9. openwrt 添加luci选项
  10. JavaSE复习_6 枚举类
  11. 互联网架构介绍 --from 光荣之路
  12. Charles 使用教程
  13. Mac OS 如何批量转换图片格式
  14. 技嘉主板BIOS修改风扇转速设置详细教程
  15. ubuntu设置桌面和锁屏背景
  16. SpringBoot 项目(若依脚手架)2
  17. oeasy教您玩转vim - 2 - # 使用帮助
  18. 蒸鱼的七�秘密八�做法 【精美�文】
  19. 带你玩转Visual Studio——Property Manager的配制
  20. Linux m4a转mp3

热门文章

  1. 转:高效代码审查的八条准则和十个经验
  2. 线程问题—一个线程怎么调出另外一个线程的结果。
  3. css教程–十步学会用css建站(全)
  4. (原) Data Blocks, Extents, and Segments
  5. 阿里面试题——Java对象初始化
  6. 每一个工程师都要学的安全测试,老板再也不用担心服务器被黑
  7. 适用于 deno 的多版本管理工具 dvm 发布
  8. 使用php蓝天采集器抓取今日头条ajax的文章内容
  9. SQL 语句递归查询 With AS 查找所有子节点
  10. 超级详细的Tcpdump的用法