举例详解Python中yield生成器的用法


Posted in Python onAugust 05, 2015

yield是生成的意思,但是在python中则是作为生成器理解,生成器的用处主要可以迭代,这样简化了很多运算模型(还不是很了解是如何简化的)。
yield是一个表达式,是有返回值的.
当一个函数中含有yield时,它不再是一个普通的函数,而是一个生成器.当该函数被调用时不会自动执行,而是暂停,见第一个例子:
例1:

>>> def mygenerator():
...  print 'start...'
...  yield 5
... 
>>> mygenerator()   //在此处调用,并没有打印出start...说明存在yield的函数没有被运行,即暂停
<generator object mygenerator at 0xb762502c>
>>> mygenerator().next()  //调用next()即可让函数运行.
start...
5
>>>

如一个函数中出现多个yield则next()会停止在下一个yield前,见例2:
例2:

>>> def mygenerator():
...  print 'start...'
...  yield 5
... 
>>> mygenerator()   //在此处调用,并没有打印出start...说明存在yield的函数没有被运行,即暂停
<generator object mygenerator at 0xb762502c>
>>> mygenerator().next()  //调用next()即可让函数运行.
start...
5
>>>

为什么yield 5会输出5,yield 23会输出23?
我们猜测可能是因为yield是表达式,存在返回值.
那么这是否可以认为yield 5的返回值一定是5吗?实际上并不是这样,这个与send函数存在一定的关系,这个函数实质上与next()是相似的,区别是send是传递yield表达式的值进去,而next不能传递特定的值,只能传递None进去,因此可以认为g.next()和g.send(None)是相同的。见例3:
例3:

>>> def fun():
...  print 'start...'
...  m = yield 5
...  print m
...  print 'middle...'
...  d = yield 12
...  print d
...  print 'end...'
... 
>>> m = fun()    //创建一个对象
>>> m.next()    //会使函数执行到下一个yield前
start...
5
>>> m.send('message')  //利用send()传递值
message     //send()传递进来的 
middle...
12
>>> m.next()
None      //可见next()返回值为空
end...
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
StopIteration

在multiprocess中的使用

python在处理数据的时候,memory-heavy 的数据往往会导致程序没办反运行或者运行期间服务器其他程序效率受到影响。这种情况往往会把数据集合变为通过genertor来遍历。

但同时如我们所知,generoter看似只能被单进程消费,这样效率很低。
generator 可以被pool.map消费。

看一下pool.py的源码。

for i, task in enumerate(taskseq):
  ...
  try:
   put(task)
  except IOError:
   debug('could not put task on queue')
   break

实际是先将generator全部消费掉放到queue中。然后通过map来并行。这样是解决了使用map来并行。

但是依然没有解决占用内存的问题。这里有两步占用内存。

  1.     第一步是全部消费掉的generator。
  2.     第二步并行运算全部data。

解决第一个问题,通过部分消费generator来达到。
解决第二个问题,可以通过imap来达到.

示例代码如下:

import multiprocessing as mp
import itertools
import time


def g():
 for el in xrange(50):
  print el
  yield el

import os

def f(x):
 time.sleep(1)
 print str(os.getpid()) +" "+ str(x)
 return x * x

if __name__ == '__main__':
 pool = mp.Pool(processes=4)    # start 4 worker processes
 go = g()
 result = []
 N = 11
 while True:
  g2 = pool.imap(f, itertools.islice(go, N))
  if g2:
   for i in g2:
    result.append(i)
    time.sleep(1)
  else:
   break
 print(result)

ps: 使用注意事项。在produce数据的时候,尽量少做操作,应为即使是map也是单线程的来消费数据。所以尽量把操作放到map中作。这样才能更好的利用多进程提高效率。

Python 相关文章推荐
用Python制作简单的朴素基数估计器的教程
Apr 01 Python
Python的dict字典结构操作方法学习笔记
May 07 Python
Python中属性和描述符的正确使用
Aug 23 Python
详解Python中表达式i += x与i = i + x是否等价
Feb 08 Python
Python实现的选择排序算法原理与用法实例分析
Nov 22 Python
pandas将DataFrame的列变成行索引的方法
Apr 10 Python
spark: RDD与DataFrame之间的相互转换方法
Jun 07 Python
Django添加sitemap的方法示例
Aug 06 Python
python lxml中etree的简单应用
May 10 Python
Python 操作 ElasticSearch的完整代码
Aug 04 Python
python读写Excel表格的实例代码(简单实用)
Dec 19 Python
keras实现VGG16 CIFAR10数据集方式
Jul 07 Python
Python中return语句用法实例分析
Aug 04 #Python
python函数形参用法实例分析
Aug 04 #Python
Python简明入门教程
Aug 04 #Python
将Python代码打包为jar软件的简单方法
Aug 04 #Python
python函数局部变量用法实例分析
Aug 04 #Python
python删除列表内容
Aug 04 #Python
解决Python传递中文参数的问题
Aug 04 #Python
You might like
PHP实现定时生成HTML网站首页实例代码
2008/11/20 PHP
PHP实现在windows下配置sendmail并通过mail()函数发送邮件的方法
2017/06/20 PHP
简单谈谈jQuery(function(){})与(function(){})(jQuery)
2014/12/19 Javascript
js实现简洁的滑动门菜单(选项卡)效果代码
2015/09/04 Javascript
详解jQuery Mobile自定义标签
2016/01/06 Javascript
浅析JS异步加载进度条
2016/05/05 Javascript
浅谈js多维数组和hash数组定义和使用
2016/07/27 Javascript
jquery实现文本框的禁用和启用
2016/12/07 Javascript
Bootstrap table表格简单操作
2017/02/07 Javascript
AngularJS入门教程一:路由用法初探
2017/05/27 Javascript
JavaScript实现选中文字提示新浪微博分享效果
2017/06/15 Javascript
详解AngularJS2 Http服务
2017/06/26 Javascript
jQuery实现可兼容IE6的遮罩功能详解
2017/09/19 jQuery
js 只比较时间大小的实例
2017/10/26 Javascript
JavaScript如何对图片进行黑白化
2018/04/10 Javascript
vue实现组件之间传值功能示例
2018/07/13 Javascript
js实现小星星游戏
2020/03/23 Javascript
详解Vue.js 响应接口
2020/07/04 Javascript
js实现星星海特效的示例
2020/09/28 Javascript
node.js获取参数的常用方法(总结)
2017/05/29 Python
使用Python来开发微信功能
2018/06/13 Python
Python使用ctypes调用C/C++的方法
2019/01/29 Python
学习python可以干什么
2019/02/26 Python
CSS3 icon font完全指南(CSS3 font 会取代icon图标)
2013/01/06 HTML / CSS
露营世界:Camping World
2017/02/02 全球购物
蛋白质世界:Protein World
2017/11/23 全球购物
卡西欧G-SHOCK英国官网: 防水防震手表
2018/01/08 全球购物
大学本科毕业生求职信范文
2013/12/18 职场文书
关于毕业的广播稿
2014/01/10 职场文书
元旦晚会邀请函
2014/01/27 职场文书
中餐厅主管的职责范文
2014/02/04 职场文书
党员干部群众路线个人整改措施
2014/09/18 职场文书
法务专员岗位职责
2015/02/14 职场文书
2015年财务人员工作总结
2015/04/10 职场文书
2016关于学习党章的心得体会
2016/01/15 职场文书
浅谈vue2的$refs在vue3组合式API中的替代方法
2021/04/18 Vue.js