(转) Python Generators(生成器)——yield关键字
http://blog.csdn.net/scelong/article/details/6969276
生成器是这样一个函数,它记住上一次返回时在函数体中的位置。对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。
生成器不仅“记住”了它数据状态;生成器还“记住”了它在流控制构造(在命令式编程中,这种构造不只是数据值)中的位置。
生成器的特点:
生成器是一个函数,而且函数的参数都会保留。
迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的
在python中,yield就是这样的一个生成器。
yield 生成器的运行机制:
当你问生成器要一个数时,生成器会执行,直至出现 yield 语句,生成器把
yield 的参数给你,之后生成器就不会往下继续运行。 当你问他要下一个数时,他会从上次的状态。开始运行,直至出现yield语句,把参数给你,之后停下。如此反复 直至退出函数。(以上关于yield的描述,在后面列举一个简单的例子来解释这段话)
yield的使用:
在python中,当你定义一个函数,使用了yield关键字时,这个函数就是一个生成器,它的执行会和其他普通的函数有很多不同,函数返回的是一个对象,而不是你平常 所用return语句那样,能得到结果值。如果想取得值,那得调用next()函数,如:
- c = h() #h()包含了yield关键字
- #返回值
- c.next()
每当调用一次迭代器的next函数,生成器函数运行到yield之处,返回yield后面的值且在这个地方暂停,所有的状态都会被保持住,直到下次next函数被调用,或者碰到异常循环退出。
下面,来看看以下的例子代码吧,是用来说明yield运行机制的。
- def fib(max):
- a, b = 1, 1
- while a < max:
- yield a #generators return an iterator that returns a stream of values.
- a, b = b, a+b
程序运行:
- for n in fib(15):
- print n
从前面的运行机制描述中,可以获知,程序运行到yield这行时,就不会继续往下执行。而是返回一个包含当前函数所有参数的状态的iterator对象。目的就是为了第二次被调用时,能够访问到函数所有的参数值都是第一次访问时的值,而不是重新赋值。
程序第一次调用时:
- def fib(max):
- a, b = 1, 1
- while a < max:
- yield a #这时a,b值分别为1,1,当然,程序也在执行到这时,返回
- 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对象。
等待第三次的调用....
- def fib(max):
- a, b = 1, 1
- while a < max:
- yield a
- a, b = b, a+b
通过上面的分析,可以一次类推的展示了yield的详细运行过程了!
通过使用生成器的语法,可以免去写迭代器类的繁琐代码,如,上面的例子使用迭代类来实现,代码如下:
- class Fib:
- def __init__(self, max):
- self.max = max
- def __iter__(self):
- self.a = 0
- self.b = 1
- return self
- def next(self):
- fib = self.a
- if fib > self.max:
- raise StopIteration
- self.a, self.b = self.b, self.a + self.b
- return fib
yield其他例子展示:排列,组合
#生成全排列
- def perm(items, n = None):
- if n is None:
- n = len(items)
- for i in range(len(items)):
- v = items[i:i+1]
- if n==1:
- yield v
- else:
- rest = items[:i] + items[i+1:]
- for p in perm(rest, n-1):
- yield v + p
- def comb(items, n = None):
- if n is None:
- n = len(items)
- else:
- for i in range(len(items)):
- v = items[i:i+1]
- if 1 == n:
- yield v
- else:
- rest = items[i+1:]
- for c in comb(rest, n-1):
- yield v + c
(转) Python Generators(生成器)——yield关键字的更多相关文章
- Python Generators(生成器)--yield
参考:http://blog.csdn.net/scelong/article/details/6969276 Python生成器 什么是python生成器,意思是带有一个yield语句的函数,既然它 ...
- Python:笔记(7)——yield关键字
Python:笔记(7)——yield关键字 yield与生成器 所谓生成器是一个函数,它可以生成一个值的序列,以便在迭代中使用.函数使用yield关键字可以定义生成器对象. 一个例子 我们调用该函数 ...
- 解析Python中的yield关键字
前言 python中有一个非常有用的语法叫做生成器,所利用到的关键字就是yield.有效利用生成器这个工具可以有效地节约系统资源,避免不必要的内存占用. 一段代码 def fun(): for i i ...
- [PY3]——函数——生成器(yield关键字)
函数—生成器篇 1. 认识和区分可迭代or生成器 1.1 可迭代对象 当你建立了一个列表,你可以逐项地读取这个列表,这叫做一个可迭代对象 当你使用一个列表生成式来建立一个列表的时候,就建立了一个可迭代 ...
- python中的yield关键字
yield关键字一直困扰了我很久,一直也没有弄明白,现在将暂时理解的yield记录如下,供参考: 关键词:可迭代对象,生成器,迭代器 一.可迭代对象: 可迭代对象:可迭代对象是一个泛称,只要可以用fo ...
- 深入理解python中的yield关键字
想必大家都看过这样的代码: 上面的这段代码会计算0-9的平方并打印出来. 那么问题来了,这段代码和我们要说的东西有什么区别呢? 这里的关键字,yield,我在前面的文章里已经发过了.那么yield是什 ...
- python yield 关键字
最近看代码看到python里面的yield关键字,和我之前接触的语言好像都没有来着,我就查了查它的含义,大概理解如下: >>> def createGenerator(): ... ...
- PHP性能优化利器:生成器 yield理解
如果是做Python或者其他语言的小伙伴,对于生成器应该不陌生.但很多PHP开发者或许都不知道生成器这个功能,可能是因为生成器是PHP 5.5.0才引入的功能,也可以是生成器作用不是很明显.但是,生成 ...
- Python列表生成器
本篇将介绍python生成器,更多内容请参考:python学习指南 前言 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不 ...
随机推荐
- POJ 1607
#include<iostream> #include<iomanip> using namespace std; int main() { //freopen("a ...
- C# 调用Windows API实现两个进程间的通信
使用Windows API实现两个进程间(含窗体)的通信http://blog.csdn.net/huangxinfeng/article/details/5513608 从C#下使用WM_COPYD ...
- hdu 4259 Double Dealing
思路: 找每一个数的循环节,注意优化!! 每次找一个数的循环节时,记录其路径,下次对应的数就不用再找了…… 代码如下: #include<iostream> #include<cst ...
- 记一段使用node对mysql数据库做处理
所用到的存储过程如下: temp_get_userCount: BEGIN #Routine body goes here... SELECT COUNT(id) as num FROM tbl_us ...
- php 修改 AppServ 下Apache 端口
php 修改 AppServ 下Apache 端口 步骤一:把 C:\AppServ\Apache2.2\conf 中httpd.conf修改了 还不正确 步骤二:把httpd.conf 中List ...
- sqlserver 分页
SQL语句: create PROCEDURE [dbo].[GetPageDataOutRowNumber] ( @tn nvarchar(),--表名称 @idn nvarchar(),--表主键 ...
- lintcode:格雷编码
格雷编码 格雷编码是一个二进制数字系统,在该系统中,两个连续的数值仅有一个二进制的差异. 给定一个非负整数 n ,表示该代码中所有二进制的总数,请找出其格雷编码顺序.一个格雷编码顺序必须以 0 开始, ...
- eclipse导入maven项目后依赖jar包更新问题->update project按钮
eclipse导入maven项目后依赖jar包更新问题 1.eclipse有专门的导入maven项目按钮,file-import-maven project,eclipse会自动查找指定路径下的pom ...
- mysql代码里面有中文注释导致语法错误
一个简单的创建表的代码 DROP database IF exists reg_login; CREATE database reg_login; use reg_login --用户表 create ...
- linux下jdk安装 failed /usr/local/jdk1.6.0_10/jre/lib/i386/client/libjvm.so
今天在fedora core 4下面安装jdk1.6后,运行java -version,没有出现相关的版本信息,而是出现了以下错误: dl failure on line 685Error: fail ...