关于Python中的yield

 

在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor)。

一、迭代器(iterator)

在Python中,for循环可以用于Python中的任何类型,包括列表、元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器

迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引发StopIteration。任何这类的对象在Python中都可以用for循环或其他遍历工具迭代,迭代工具内部会在每次迭代时调用next方法,并且捕捉StopIteration异常来确定何时离开。

使用迭代器一个显而易见的好处就是:每次只从对象中读取一条数据,不会造成内存的过大开销。

比如要逐行读取一个文件的内容,利用readlines()方法,我们可以这么写:

1
2
for line in open("test.txt").readlines():
print line

这样虽然可以工作,但不是最好的方法。因为他实际上是把文件一次加载到内存中,然后逐行打印。当文件很大时,这个方法的内存开销就很大了。

利用file的迭代器,我们可以这样写:

1
2
for line in open("test.txt"):   #use file iterators
print line

这是最简单也是运行速度最快的写法,他并没显式的读取文件,而是利用迭代器每次读取下一行。

二、生成器(constructor)

生成器函数在Python中与迭代器协议的概念联系在一起。简而言之,包含yield语句的函数会被特地编译成生成器。当函数被调用时,他们返回一个生成器对象,这个对象支持迭代器接口。函数也许会有个return语句,但它的作用是用来yield产生值的。

不像一般的函数会生成值后退出,生成器函数在生成值后会自动挂起并暂停他们的执行和状态,他的本地变量将保存状态信息,这些信息在函数恢复时将再度有效

1
2
3
4
5
6
7
8
>>> def g(n):
... for i in range(n):
... yield i **2
...
>>> for i in g(5):
... print i,":",
...
0 : 1 : 4 : 9 : 16 :

要了解他的运行原理,我们来用next方法看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> t = g(5)
>>> t.next()
0
>>> t.next()
1
>>> t.next()
4
>>> t.next()
9
>>> t.next()
16
>>> t.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

在运行完5次next之后,生成器抛出了一个StopIteration异常,迭代终止。
再来看一个yield的例子,用生成器生成一个Fibonacci数列:

1
2
3
4
5
6
7
8
9
10
def fab(max):
a,b = 0,1
while a < max:
yield a
a, b = b, a+b
 
>>> for i in fab(20):
... print i,",",
...
0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 ,

关于Python中的yield的更多相关文章

  1. 深入理解Python中的yield和send

    send方法和next方法唯一的区别是在执行send方法会首先把上一次挂起的yield语句的返回值通过参数设定,从而实现与生成器方法的交互. 但是需要注意,在一个生成器对象没有执行next方法之前,由 ...

  2. [转]关于Python中的yield

    在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor). 一.迭代器(iterator) 在Python中,for循环可以用于Python中的任何 ...

  3. 【转载】关于Python中的yield

    在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor). 一.迭代器(iterator) 在Python中,for循环可以用于Python中的任何 ...

  4. 关于Python中的yield(转载)

    您可能听说过,带有 yield 的函数在 Python 中被称之为 generator(生成器),何谓 generator ? 我们先抛开 generator,以一个常见的编程题目来展示 yield ...

  5. Python中的yield生成器的简单介绍

    Python yield 使用浅析(整理自:廖 雪峰, 软件工程师, HP 2012 年 11 月 22 日 ) 初学 Python 的开发者经常会发现很多 Python 函数中用到了 yield 关 ...

  6. Python中的yield和Generators(生成器)

    本文目的 解释yield关键字到底是什么,为什么它是有用的,以及如何来使用它. 协程与子例程 我们调用一个普通的Python函数时,一般是从函数的第一行代码开始执行,结束于return语句.异常或者函 ...

  7. python 中的 yield 究竟为何物?生成器和迭代器的区别?

    当你突然看到别人的代码中出现了一个好像见过但又没用过的关键词 比如 yield ,你是否会觉得这段代码真是高大上呢? 或许只有我这种小白才会这样子觉得,就在刚刚,我就看见了别人的代码中的yield,觉 ...

  8. python中的yield

    在理解yield之前,要首先明白什么是generator,在理解generator之前首先要理解可迭代的概念. 可迭代(iterables)在你创建一个list的时候,可以逐个读取其中的元素,该逐个读 ...

  9. 解析Python中的yield关键字

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

随机推荐

  1. Web前端代码规范与页面布局

    一.    规范目的: 为提高工作效率,便于后台人员添加功能及前端后期优化维护,输出高质量的文档,在网站建设中,使结构更加清晰,代码简明有序,有一个更好的前端架构,有利于SEO优化.   二.     ...

  2. 代码快捷键的设置读取App.config方法

    附件下载:http://files.cnblogs.com/files/qtiger/ShortcutAchieve.zip 代码实现最重要(增加引用using System.Configuratio ...

  3. Cassandra 技术选型的问题

    Cassandra在国内资料少,用的也不多,大家更多抱观望态度吧. 为了扩大Cassandra队伍帮助自己采坑,决定写一篇文章,就自己对Cassandra的理解范围进行介绍. 选用Cassandra的 ...

  4. KMP串匹配算法解析与优化

    朴素串匹配算法说明 串匹配算法最常用的情形是从一篇文档中查找指定文本.需要查找的文本叫做模式串,需要从中查找模式串的串暂且叫做查找串吧. 为了更好理解KMP算法,我们先这样看待一下朴素匹配算法吧.朴素 ...

  5. PHP 表单 - 验证邮件和URL

    PHP - 验证名称 以下代码将通过简单的方式来检测 name 字段是否包含字母和空格,如果 name 字段值不合法,将输出错误信息: $name = test_input($_POST[" ...

  6. Spring中Quartz调度器的使用

    一.Quartz的特点 * 按作业类的继承方式来分,主要有以下两种: 1.作业类继承org.springframework.scheduling.quartz.QuartzJobBean类的方式 2. ...

  7. 升级Mac X Mavericks MacMiv 无法启动

    今天把Mac 系统升级到了 Mac X Mavericks ,确实有不少的惊喜.虽然体验不出Mac X Mavericks拥有更强的性能/更好的电池表现,但是新版的Safari浏览器的提供了更方便的主 ...

  8. Keil的使用方法 - 常用功能(二)

    Ⅰ.概述 上一篇文章是总结关于Keil使用方法-常用功能(一),关于(文件和编译)工具栏每一个按钮的功能描述和快捷键的使用. 我将每一篇Keil使用方法的文章都汇总在一起,回顾前面的总结请点击下面的链 ...

  9. 第一步 django的下载安装

    django是python众多web框架中比较有名的一个,以大包大揽功能俱全而著名.但作为重量级的web框架,难免性能上回有所损失,不过由于其封装了各种API,在开发的时候会便利许多.所以也是深受欢迎 ...

  10. JLINK V8 Keil MDK4.10 STM32

    新买的JLINK v8仿真器,第一次使用,编译环境是Keil MDK4.10,目前芯片是STM32F103x. 按照光盘的说明先安装了驱动,USB接上JLINK v8,显示驱动成功.但是在debug或 ...