彻底理解 Python 生成器
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
<generator object <genexpr> 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):

好了,话不多说,翠花,上栗子:
#encoding:UTF-8
def yield_test(n):
for i in range(n):
yield call(i)
print("i=",i)
print("Done.") def call(i):
return i*2 for i in yield_test(5):
print(i,",")
结果:
>>>
0 ,
i= 0
2 ,
i= 1
4 ,
i= 2
6 ,
i= 3
8 ,
i= 4
Done.
>>>
理解的关键在于:下次迭代时,代码从yield的下一条语句开始执行。
总结:
什么是生成器?
生成器仅仅保存了一套生成数值的算法,并且没有让这个算法现在就开始执行,而是我什么时候调它,它什么时候开始计算一个新的值,并给你返回。
练习题:
def count_down(n):
while n >= 0:
newn = yield n
print('newn', newn)
if newn:
print('if')
n = newn
print('n =', n)
else:
n -= 1 cd = count_down(5)
for i in cd:
print(i, ',')
if i == 5:
cd.send(3)
结果:

彻底理解 Python 生成器的更多相关文章
- 深入理解Python生成器(Generator)
我们可以通过列表生成式简单直接地创建一个列表,但是受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,而且如果我们仅仅需要访问前面几个元素,那后面绝大多 ...
- 完全理解 Python 迭代对象、迭代器、生成器(转)
完全理解 Python 迭代对象.迭代器.生成器 本文源自RQ作者的一篇博文,原文是Iterables vs. Iterators vs. Generators » nvie.com,俺写的这篇文章是 ...
- 完全理解 Python 迭代对象、迭代器、生成器
完全理解 Python 迭代对象.迭代器.生成器 2017/05/29 · 基础知识 · 9 评论 · 可迭代对象, 生成器, 迭代器 分享到: 原文出处: liuzhijun 本文源自RQ作者 ...
- 怎么理解Python迭代器与生成器?
怎么理解Python迭代器与生成器?在Python中,使用for ... in ... 可以对list.tuple.set和dict数据类型进行迭代,可以把所有数据都过滤出来.如下: ...
- 深入理解python的yield和generator
原文发表在我的博客主页,转载请注明出处 前言 没有用过的东西,没有深刻理解的东西很难说自己会,而且被别人一问必然破绽百出.虽然之前有接触过python协程的概念,但是只是走马观花,这两天的一次交谈中, ...
- python——生成器
python——生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个 ...
- 深入理解 Python 异步编程(上)
http://python.jobbole.com/88291/ 前言 很多朋友对异步编程都处于"听说很强大"的认知状态.鲜有在生产项目中使用它.而使用它的同学,则大多数都停留在知 ...
- 深入理解Python异步编程(上)
本文代码整理自:深入理解Python异步编程(上) 参考:A Web Crawler With asyncio Coroutines 一.同步阻塞方式 import socket def blocki ...
- python生成器(generator)、迭代器(iterator)、可迭代对象(iterable)区别
三者联系 迭代器(iterator)是一个更抽象的概念,任何对象,如果它的类有next方法(next python3)和__iter__方法返回自己本身,即为迭代器 通常生成器是通过调用一个或多个yi ...
随机推荐
- Buaaclubs项目介绍
简介 首先,它是社团资讯的集散地,任何希望了解北航社团信息或活动情况的同学都可以在这个平台上获取自己需要的信息,并且可以随时随地地参与社团互动,方便快捷地实现网上报名.在线咨询.活动参与等多种功能. ...
- 实验三 敏捷开发和XP实验
课程:Java程序设计实验 班级:1352 姓名: 于佳心 学号:20135206 成绩: 指导教师:娄嘉鹏 ...
- my everying
evering -> everything 一.请回望暑假时的第一次作业,你对于软件工程课程的想象 1)对比开篇博客你对课程目标和期待,"希望通过实践锻炼,增强计算机专业的能力和就业竞 ...
- 使用java开发微信公众平台(1)
目录 开发服务器 域名验证 获取access_token 自定义菜单 个人账号不能定义url访问服务器,使用测试号就不用认证添加url了,进入公众平台测试账号 开发服务器 域名验证 进入公众平台测试账 ...
- wait 和 sleep 区别
/* wait 和 sleep 区别? 1,wait可以指定时间也可以不指定. sleep必须指定时间. 2,在同步中时,对cpu的执行权和锁的处理不同. wait:释放执行权,释放锁. sleep: ...
- angularJS1笔记-(7)-控制器的合理使用(显示和隐式的依赖注入)
AngularJS依赖注入 1.隐式注入:不需要开发人员干预,angularJS自动根据参数的名称识别和注入数据 app.controller("myCtrl".function( ...
- Jenkins权限控制-Role Strategy Plugin插件使用
Role Strategy Plugin插件可以对构建的项目进行授权管理,让不同的用户管理不同的项目,将测试和生产环境分开. 具体配置方法如下(操作需要管理员用户权限). Jenkins版本:1.64 ...
- [转帖漫画]什么是 MD5 算法?---摘要算法 具体算法 一直搞不清楚
漫画:什么是 MD5 算法? 2017-10-05 20:16 来源:伯乐专栏作者/玻璃猫,微信公众号 - 梦见 好文投稿, 请点击 → 这里了解详情 梦见 摘要哈希生成的正确姿势是什么样呢?分三步: ...
- Android Service执行unbind后再次执行bind的问题
在执行了startService.bindService.unbindService之后,再次执行bindService.这时发现Service的onBind方法并没有执行,而是执行的onRebind ...
- 先验算法(Apriori algorithm) - 机器学习算法
Apriori is an algorithm for frequent item set mining and association rule learning over transactiona ...