• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell
您的位置:首页 > 脚本语言 >python > Python中的生成器和yield详细介绍

Python中的生成器和yield详细介绍

作者:junjie 字体:[增加 减小] 来源:互联网

junjie 通过本文主要向大家介绍了python yield,python yield函数,python中yield,python3 yield,python yield send等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

列表推导与生成器表达式

当我们创建了一个列表的时候,就创建了一个可以迭代的对象:
>>> squares=[n*n for n in range(3)]
>>> for i in squares:
 print i
 
0
1
4
</div>
这种创建列表的操作很常见,称为列表推导。但是像列表这样的迭代器,比如str、file等,虽然用起来很方便,但有一点,它们是储存在内存中的,如果值很大,会很麻烦。

而生成器表达式不同,它执行的计算与列表包含相同,但会迭代的生成结果。它的语法与列表推导一样,只是要用小括号来代替中括号:
>>> squares=(n*n for n in range(3))
>>> for i in squares:
 print i
 
0
1
4
</div>
生成器表达式不会创建序列形式的对象,不会把所有的值都读取到内存中,而是会创建一个通过迭代并按照需求生成值的生成器对象(Generator)。

那么,还有没有其它方法来产生生成器呢?

例子:斐波那契数列

例如有个需求,要生成斐波那契数列的前10位,我们可以这样写:
def fib(n):
    result=[]
    a=1
    b=1
    result.append(a)
    for i in range(n-1):
        a,b=b,a+b
        result.append(a)
    return result
if __name__=='__main__':
    print fib(10)
</div>
数字很少时,函数运行良好,但数字很多时,问题就来了,显然生成一个几千几万长度的列表并不是一个很好的主意。

这样,需求就变成了:写一个可以生成可迭代对象的函数,或者说,不要让函数一次返回全部的值,而是一次返回一个值。

这好像与我们的常识相违背,当我们调用一个普通的Python函数时,一般是从函数的第一行代码开始执行,结束于return语句、异常或者函数结束(可以看作隐式的返回None):
def fib(n):
    a=1
    b=1
    for i in range(n-1):
        a,b=b,a+b
        return a
if __name__=='__main__':
    print fib(10)
>>>
1    #返回第一个值时就卡住了
</div>
函数一旦将控制权交还给调用者,就意味着全部结束。函数中做的所有工作以及保存在局部变量中的数据都将丢失。再次调用这个函数时,一切都将从头创建。函数只有一次返回结果的机会,因而必须一次返回所有的结果。通常我们都这么认为的。但是,如果它们并非如此呢?请看神奇的yield:
def fib(n):
    a=1
    yield a
    b=1
    for i in range(n-1):
        a,b=b,a+b
        yield a
if __name__=='__main__':
    for i in fib(10):
        print i
>>>
1
1
2
3
5
8
13
21
34
</div>

生成器Generator

python中生成器的定义很简单,使用了yield关键字的函数就可以称之为生成器,它生成一个值的序列:
def countdown(n):
    while n>0:
        yield n
        n-=1
if __name__=='__main__':
    for i in countdown(10):
        print i
</div>
生成器函数返回生成器。要注意的是生成器就是一类特殊的迭代器。作为一个迭代器,生成器必须要定义一些方法,其中一个就是__next__()。如同迭代器一样,我们可以使用next()函数(Python3是__next__() )来获取下一个值:
>>> c=countdown(10)
>>> c.next()
10
>>> c.next()
9
</div>
每当生成器被调用的时候,它会返回一个值给调用者。在生成器内部使用yield来完成这个动作。为了记住yield到底干了什么,最简单的方法是把它当作专门给生成器函数用的特殊的return。调用next()时,生成器函数不断的执行语句,直至遇到yield为止,此时生成器函数的”状态”会被冻结,所有的变量的值会被保留下来,下一行要执行的代码的位置也会被记录,直到再次调用next()继续执行yield之后的语句。

next()不能无限执行,当迭代结束时,会抛出StopIteration异常。迭代未结束时,如果你想结束生成器,可以使用close()方法。
>>> c.next()
1
>>> c.next()
StopIteration
>>> c=countdown(10)
>>> c.next()
10
>>> c.close()
>>> c.next()
StopIteration
</div>
协程与yield表达式

yield语句还有更给力的功能,作为一个语句出现在赋值运算符的右边,接受一个值,或同时生成一个值并接受一个值。
def recv():
    print 'Ready'
    while True:
        n=yield
        print 'Go %s'%n
>>> c=recv()
>>> c.next()
Ready
>>> c.send(1)
Go 1
>>> c.send(2)
Go 2
</div>
以这种方式使用yield语句的函数称为协程。在这个例子中,对于next()的初始调用是必不可少的,这样协程才能执行可通向第一个yield表达式的语句。在这里协程会挂起,等待相关生成器对象send()方法给它发送一个值。传递给send()的值由协程中的yield表达式返回。

协程的运行一般是无限期的,使用方法close()可以显式的关闭它。

如果yield表达式中提供了值,协程可以使用yield语句同时接收和发出返回值。
def split_line():
    print 'ready to split'
    resul

您可能想查找下面的文章:

  • python生成式的send()方法(详解)
  • 浅析Python中yield关键词的作用与用法
  • 基于python yield机制的异步操作同步化编程模型
  • Python yield 使用浅析
  • Python yield 使用浅析
  • Python中生成器和yield语句的用法详解
  • 初步解析Python中的yield函数的用法
  • python通过yield实现数组全排列的方法
  • Python中的生成器和yield详细介绍
  • Python中的生成器和yield详细介绍

相关文章

  • Python3写入文件常用方法实例分析
  • python利用elaphe制作二维条形码实现代码
  • Python中的推导式使用详解
  • centos系统升级python 2.7.3
  • 一键搞定python连接mysql驱动有关问题(windows版本)
  • Python实现Mysql数据库连接池实例详解
  • Python面向对象编程中的类和对象学习教程
  • Pyhthon中使用compileall模块编译源文件为pyc文件
  • 使用Python发送邮件附件以定时备份MySQL的教程
  • python判断一个集合是否包含了另外一个集合中所有项的方法

文章分类

  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell

最近更新的内容

    • 删除目录下相同文件的python代码(逐级优化)
    • Python中isnumeric()方法的使用简介
    • Python新手在作用域方面经常容易碰到的问题
    • Django查找网站项目根目录和对正则表达式的支持
    • 简单谈谈python的反射机制
    • Python实现TCP协议下的端口映射功能的脚本程序示例
    • 为Python的web框架编写前端模版的教程
    • python3中bytes和string之间的互相转换
    • python为tornado添加recaptcha验证码功能
    • python获取远程图片大小和尺寸的方法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有