http://blog.csdn.net/scelong/article/details/6969276

生成器是这样一个函数,它记住上一次返回时在函数体中的位置。对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。

生成器不仅“记住”了它数据状态;生成器还“记住”了它在流控制构造(在命令式编程中,这种构造不只是数据值)中的位置。

生成器的特点

生成器是一个函数,而且函数的参数都会保留。

迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的

在python中,yield就是这样的一个生成器。

yield 生成器的运行机制:

当你问生成器要一个数时,生成器会执行,直至出现 yield 语句,生成器把

yield 的参数给你,之后生成器就不会往下继续运行。 当你问他要下一个数时,他会从上次的状态。开始运行,直至出现yield语句,把参数给你,之后停下。如此反复 直至退出函数。(以上关于yield的描述,在后面列举一个简单的例子来解释这段话)

yield的使用

在python中,当你定义一个函数,使用了yield关键字时,这个函数就是一个生成器,它的执行会和其他普通的函数有很多不同,函数返回的是一个对象,而不是你平常 所用return语句那样,能得到结果值。如果想取得值,那得调用next()函数,如:

  1. c = h() #h()包含了yield关键字
  2. #返回值
  3. c.next()

每当调用一次迭代器的next函数,生成器函数运行到yield之处,返回yield后面的值且在这个地方暂停,所有的状态都会被保持住,直到下次next函数被调用,或者碰到异常循环退出。

下面,来看看以下的例子代码吧,是用来说明yield运行机制的。

  1. def fib(max):
  2. a, b = 1, 1
  3. while a < max:
  4. yield a #generators return an iterator that returns a stream of values.
  5. a, b = b, a+b

程序运行:

  1. for n in fib(15):
  2. print n

从前面的运行机制描述中,可以获知,程序运行到yield这行时,就不会继续往下执行。而是返回一个包含当前函数所有参数的状态的iterator对象。目的就是为了第二次被调用时,能够访问到函数所有的参数值都是第一次访问时的值,而不是重新赋值。

程序第一次调用时:

  1. def fib(max):
  2. a, b = 1, 1
  3. while a < max:
  4. yield a #这时a,b值分别为1,1,当然,程序也在执行到这时,返回
  5. a, b = b, a+b

程序第二次调用时:

从前面可知,第一次调用时,a,b=1,1,那么,我们第二次调用时(其实就是调用第一次返回的iterator对象的next()方法),程序跳到yield语句处,

执行a,b = b, a+b语句,此时值变为:a,b = 1, (1+1) => a,b = 1, 2

程序继续while循环,当然,再一次碰到了yield a 语句,也是像第一次那样,保存函数所有参数的状态,返回一个包含这些参数状态的iterator对象。

等待第三次的调用....

  1. def fib(max):
  2. a, b = 1, 1
  3. while a < max:
  4. yield a
  5. a, b = b, a+b

通过上面的分析,可以一次类推的展示了yield的详细运行过程了!

通过使用生成器的语法,可以免去写迭代器类的繁琐代码,如,上面的例子使用迭代类来实现,代码如下:

  1. class Fib:
  2. def __init__(self, max):
  3. self.max = max
  4. def __iter__(self):
  5. self.a = 0
  6. self.b = 1
  7. return self
  8. def next(self):
  9. fib = self.a
  10. if fib > self.max:
  11. raise StopIteration
  12. self.a, self.b = self.b, self.a + self.b
  13. return fib

yield其他例子展示:排列,组合

#生成全排列

    1. def perm(items, n = None):
    2. if n is None:
    3. n = len(items)
    4. for i in range(len(items)):
    5. v = items[i:i+1]
    6. if n==1:
    7. yield v
    8. else:
    9. rest = items[:i] + items[i+1:]
    10. for p in perm(rest, n-1):
    11. yield v + p
    12. def comb(items, n = None):
    13. if n is None:
    14. n = len(items)
    15. else:
    16. for i in range(len(items)):
    17. v = items[i:i+1]
    18. if 1 == n:
    19. yield v
    20. else:
    21. rest = items[i+1:]
    22. for c in comb(rest, n-1):
    23. yield v + c

(转) Python Generators(生成器)——yield关键字的更多相关文章

  1. Python Generators(生成器)--yield

    参考:http://blog.csdn.net/scelong/article/details/6969276 Python生成器 什么是python生成器,意思是带有一个yield语句的函数,既然它 ...

  2. Python:笔记(7)——yield关键字

    Python:笔记(7)——yield关键字 yield与生成器 所谓生成器是一个函数,它可以生成一个值的序列,以便在迭代中使用.函数使用yield关键字可以定义生成器对象. 一个例子 我们调用该函数 ...

  3. 解析Python中的yield关键字

    前言 python中有一个非常有用的语法叫做生成器,所利用到的关键字就是yield.有效利用生成器这个工具可以有效地节约系统资源,避免不必要的内存占用. 一段代码 def fun(): for i i ...

  4. [PY3]——函数——生成器(yield关键字)

    函数—生成器篇 1. 认识和区分可迭代or生成器 1.1 可迭代对象 当你建立了一个列表,你可以逐项地读取这个列表,这叫做一个可迭代对象 当你使用一个列表生成式来建立一个列表的时候,就建立了一个可迭代 ...

  5. python中的yield关键字

    yield关键字一直困扰了我很久,一直也没有弄明白,现在将暂时理解的yield记录如下,供参考: 关键词:可迭代对象,生成器,迭代器 一.可迭代对象: 可迭代对象:可迭代对象是一个泛称,只要可以用fo ...

  6. 深入理解python中的yield关键字

    想必大家都看过这样的代码: 上面的这段代码会计算0-9的平方并打印出来. 那么问题来了,这段代码和我们要说的东西有什么区别呢? 这里的关键字,yield,我在前面的文章里已经发过了.那么yield是什 ...

  7. python yield 关键字

    最近看代码看到python里面的yield关键字,和我之前接触的语言好像都没有来着,我就查了查它的含义,大概理解如下: >>> def createGenerator(): ... ...

  8. PHP性能优化利器:生成器 yield理解

    如果是做Python或者其他语言的小伙伴,对于生成器应该不陌生.但很多PHP开发者或许都不知道生成器这个功能,可能是因为生成器是PHP 5.5.0才引入的功能,也可以是生成器作用不是很明显.但是,生成 ...

  9. Python列表生成器

    本篇将介绍python生成器,更多内容请参考:python学习指南 前言 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不 ...

随机推荐

  1. django转义safe

    “何谓转义?就是把html语言的关键字过滤掉.例如,<div>就是html的关键字,如果要在html页面上呈现<div>,其源代码就必须是<div> 默认情况下,d ...

  2. HDU 2159 FATE (二维完全背包

    FATE http://acm.hdu.edu.cn/showproblem.php?pid=2159 Problem Description 最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备 ...

  3. hdu 4068 SanguoSHA

    搜索下就可以了…… 代码如下: #include<iostream> #include<cstring> #include<cstdio> #include< ...

  4. 传说中的WCF(4):发送和接收SOAP头

    如果你实在不明白Header是个啥玩意儿,你就想一想你发送电子邮件时,是不是有个叫“附件”的东东?对啊,那么SOAP头是不是可以理解为一种附加信息?就是附加到消息正文的内容. 消息正文又是啥?WCF除 ...

  5. 机器学习之多变量线性回归(Linear Regression with multiple variables)

    1. Multiple features(多维特征) 在机器学习之单变量线性回归(Linear Regression with One Variable)我们提到过的线性回归中,我们只有一个单一特征量 ...

  6. Windows 回调监控 <一>

    在x86的体系结构中,我们常用hook关键的系统调用来达到对系统的监控,但是对于x64的结构,因为有PatchGuard的存在,对于一些系统关键点进行hook是很不稳定的,在很大几率上会导致蓝屏的发生 ...

  7. Eclipse下Python的MySQLdb的安装以及相关问题

    前提是要安装好Python以及eclipse和MySQL的相应版本.本文Python为2.7,MySQL为5.1Eclipse为3.6.2 下载完MySQLdb以后,直接安装即可.在eclipse中启 ...

  8. [主席树]HDOJ2665 && POJ2104 && POJ2761

    主席树真是神奇的物种! Orz一篇资料 题意:给n.m   下面有n个数 (编号1到n) 有m个询问,询问的是上面的数的编号在[l,r]之间第k小的数 n.m的范围都是$10^5$ 是主席树的入门题 ...

  9. iphone 异常捕获处理

    iphone 异常捕获处理 1 void UncaughtExceptionHandler(NSException *exception) { 2 NSArray *arr = [exception ...

  10. AppWidget框架

    AppWidget 框架主要包括以下类: 1.AppWidgetProvider:继承自BroadcastReceiver,在AppWidget应用update.enable.disable和dele ...