1. 生成器定义

在Python中,一边循环一边计算的机制,称为生成器:generator。

2. 为什么要有生成器

列表所有数据都在内存中,如果有海量数据的话将会非常耗内存。

如:仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

如果列表元素按照某种算法推算出来,那我们就可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。

简单一句话:我又想要得到庞大的数据,又想让它占用空间少,那就用生成器!

3.如何创建生成器

第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

>>> L = [x * x for x in range(10)]>>>L

[0,1, 4, 9, 16, 25, 36, 49, 64, 81]>>> g = (x * x for x in range(10))>>>g at 0x1022ef630>

创建L和g的区别仅在于最外层的[]和(),L是一个list,而g是一个generator。

方法二, 如果一个函数中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator。调用函数就是创建了一个生成器(generator)对象。

4. 生成器的工作原理

(1)生成器(generator)能够迭代的关键是它有一个next()方法,

工作原理就是通过重复调用next()方法,直到捕获一个异常。

(2)带有 yield 的函数不再是一个普通函数,而是一个生成器generator。

可用next()调用生成器对象来取值。next 两种方式 t.__next__() | next(t)。

可用for 循环获取返回值(每执行一次,取生成器里面一个值)

(基本上不会用next()来获取下一个返回值,而是直接使用for循环来迭代)。

(3)yield相当于 return 返回一个值,并且记住这个返回的位置,下次迭代时,代码从yield的下一条语句开始执行。

(4).send() 和next()一样,都能让生成器继续往下走一步(下次遇到yield停),但send()能传一个值,这个值作为yield表达式整体的结果

——换句话说,就是send可以强行修改上一个yield表达式值。比如函数中有一个yield赋值,a = yield 5,第一次迭代到这里会返回5,a还没有赋值。第二次迭代时,使用.send(10),那么,就是强行修改yield 5表达式的值为10,本来是5的,那么a=10

感受下yield返回值的过程(关注点:每次停在哪,下次又开始在哪)及send()传参的通讯过程,

思考None是如何产生的(第一次取值:yield 返回了 i 值 0,停在yield i,temp没赋到值。第二次取值,开始在print,temp没被赋值,故打印None,i加1,继续while判断,yield 返回了 i 值 1,停在yield i):

好了,话不多说,翠花,上栗子:

1 #encoding:UTF-8

2 defyield_test(n):3 for i inrange(n):4 yieldcall(i)5 print("i=",i)6 print("Done.")7

8 defcall(i):9 return i*2

10

11 for i in yield_test(5):12 print(i,",")

结果:

>>>0 ,

i=02,

i= 1

4,

i= 2

6,

i= 3

8,

i= 4Done.>>>

理解的关键在于:下次迭代时,代码从yield的下一条语句开始执行。

总结:

什么是生成器?

生成器仅仅保存了一套生成数值的算法,并且没有让这个算法现在就开始执行,而是我什么时候调它,它什么时候开始计算一个新的值,并给你返回。

练习题:

defcount_down(n):while n >=0:

newn= yieldnprint('newn', newn)ifnewn:print('if')

n=newnprint('n =', n)else:

n-= 1cd= count_down(5)for i incd:print(i, ',')if i == 5:

cd.send(3)

结果:

python 生成器_彻底理解 Python 生成器相关推荐

  1. python属性_深入理解python对象及属性

    类属性和实例属性 首先来看看类属性和类实例的属性在python中如何存储,通过__dir__方法来查看对象的属性 >>> class Test(object): pass >& ...

  2. python多线程_干货|理解python多线程和多进程

    点击上方"AI遇见机器学习",选择"星标"公众号 原创干货,第一时间送达 一.多线程与多进程 在介绍Python多线程编程之前,先给大家复习一下进程和线程的概念 ...

  3. 深入理解python特性_深入理解Python特性(7)

    克隆对象 Python中的赋值语句不会创建对象的副本,只是将名称绑定到对象上.对于不可变对象也是如此.但为了处理可变对象或可变对象集合,需要一种方法来创建这些对象的"真实副本"或& ...

  4. 怎么理解python循环_如何理解Python的循环设计

    在"循环"一节,我们已经讨论了Python基本的循环语法.这一节,我们将接触更加灵活的循环方式. range() 在Python中,for循环后的in跟随一个序列的话,循环每次使用 ...

  5. 完全理解python迭代对象_完全理解Python迭代对象、迭代器、生成器

    1.assert:python assert断言是声明其布尔值必须为真的判定,如果发生异常就说明表达示为假.可以理解assert断言语句为raise-if-not,用来测试表示式,其返回值为假,就会触 ...

  6. 怎么确定迭代器后面还有至少两个值_如何理解Python中的可迭代对象、迭代器和生成器

    ▍前言 在讨论可迭代对象.迭代器和生成器之前,先说明一下迭代器模式(iterator pattern),维基百科这么解释: 迭代器是一种最简单也最常见的设计模式.它可以让用户透过特定的接口巡访容器中的 ...

  7. python的装饰器迭代器与生成器_详解python中的生成器、迭代器、闭包、装饰器

    迭代是访问集合元素的一种方式.迭代器是一个可以记住遍历的位置的对象.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退. 1|1可迭代对象 以直接作用于 for ...

  8. python iterable对象_如何理解Python中的iterable对象

    转载请注明出处:https://www.jianshu.com/u/5e6f798c903a [^*] 表示注脚,在文末可以查看对应连接,但简书不支持该语法. 首先,容器和 iterable 间没有必 ...

  9. 如何用python写数值运算_如何理解Python的数值运算?

    1 基本算术运算 1.1 使用规则 – Python解析器相当于一个简单的计算器 – Python解析器可以接受简单的算术表达式 – 运算符可以使加(+)减(-)乘(*)除(/) 1.2 实操理解 # ...

  10. python的上下文管理用哪个关键字_正确理解python中的关键字“with”与上下文管理器...

    正确理解python中的关键字"with"与上下文管理器 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  正确理解python中的关键字&quo ...

最新文章

  1. 算法:快速排序实现 定制比较函数
  2. border-radius
  3. 数据可视化:Matplotlib vs ggplot2
  4. solaris10默认防火墙软件ipfilter
  5. 为何要搞 10 年?方舟编译器专家首次回应
  6. 计算机课的情感目标是什么意思,教案中情感目标是什么.doc
  7. onready怎么加img_用插件VMarker在vue中给图片加标记
  8. 四个数据欧几里得距离_从单词嵌入到文档距离 :WMD一种有效的文档分类方法...
  9. 计算机ip 地址异常,电脑显示IP地址错误怎么办|电脑无法上网提示IP地址错误的解决方法...
  10. 字幕的嵌入AVI转RMVB
  11. chrome 设置保护眼睛颜色
  12. 聊聊 Python 代码覆盖率工具 - 大咖爱爬虫
  13. mysql 解压版安装教程
  14. Unity(一)入门:Unity Hub下载 Unity安装
  15. 2021 年 1 月程序员工资新出炉,你猜涨了多少?
  16. 【自然语言处理】【细粒度情感分析】细粒度情感分析:了解文本情感的What、How、Why
  17. 关于香港DHL与大陆DHL有什么不同?
  18. 超重车辆高速动态称重系统设计方案
  19. Python错误集锦:python: can’t open file ‘hello’: [Errno 2] No such file or directory
  20. 上海警方迅速侦破陆家嘴滨江大道杀人案

热门文章

  1. linux系统资源信息监控
  2. Cursor finalized without prior close()
  3. [AD19] 使用元器件向导为元件绘制PCB封装
  4. [数据结构] 伸展树(Splay Tree)原理及若干应用详解(无指针)
  5. js基础-(一)-基本数据类型
  6. vue省市区三级选择的实现
  7. 黑马vue实战项目-(七)订单管理页面的开发
  8. vue脚手架学习笔记
  9. Linux中文件权限(有图详细讲解)
  10. mysql备份工具命令xtra_mysql xtrabackup备份工具使用