博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python yield 使用浅析
阅读量:5975 次
发布时间:2019-06-19

本文共 2604 字,大约阅读时间需要 8 分钟。

hot3.png

Python关键字yield的作用是什么?用来干什么的? 回答: 为了理解什么是 yield,你必须理解什么是生成器。在理解生成器之前,让我们先走近迭代。

可迭代对象

当你建立了一个列表,你可以逐项地读取这个列表,这叫做一个可迭代对象:

>>> mylist = [1, 2, 3]>>> for i in mylist :...    print(i)123

mylist 是一个可迭代的对象。当你使用一个列表生成式来建立一个列表的时候,就建立了一个可迭代的对象:

>>> mylist = [x*x for x in range(3)]>>> for i in mylist :...    print(i)014

所有你可以使用 for .. in .. 语法的叫做一个迭代器:列表,字符串,文件……你经常使用它们是因为你可以如你所愿的读取其中的元素,但是你把所有的值都存储到了内存中,如果你有大量数据的话这个方式并不是你想要的。

生成器

生成器是可以迭代的,但是你 只可以读取它一次 ,因为它并不把所有的值放在内存中,它是实时地生成数据:

>>> mygenerator = (x*x for x in range(3))>>> for i in mygenerator :...    print(i)014

看起来除了把 [] 换成 () 外没什么不同。但是,你不可以再次使用 for i in mygenerator , 因为生成器只能被迭代一次:先计算出0,然后继续计算1,然后计算4,一个跟一个的…

yield关键字

yield 是一个类似 return 的关键字,只是这个函数返回的是个生成器。

>>> def createGenerator() :...    mylist = range(3)...    for i in mylist :...        yield i*i...>>> mygenerator = createGenerator() # create a generator>>> print(mygenerator) # mygenerator is an object!
>>> for i in mygenerator:... print(i)014

实例:斐波那契数列

斐波那契数列是一个非常简单的递归数列,除次一个和第二个之外,任意一个数都可由前两个数相加得到,

例一: 初级写法

结果没有问题,直接在 fab 函数中用 print 打印数字会导致该函数可复用性较差,因为 fab 函数返回 None,其他函数无法获得该函数生成的数列(不带有return功能)

def fab(max):     n, a, b = 0, 0, 1     while n < max:         print b         a, b = b, a + b         n = n + 1 >>> fab(5)  1  1  2  3  5

例二: 初级写法并且有return功能

该写法弥补了例一的弊端,在犹豫return的是一个list会占用大量的内存.如果要控制内存使用 最好还是不要用list.例似range和xrange的区别

def fab(max):     n, a, b = 0, 0, 1     L = []     while n < max:         L.append(b)         a, b = b, a + b         n = n + 1     return L >>> for n in fab(5):  ...     print n  ...  1  1  2  3  5

例三: 类方法编写迭代器

改方法配合使用__iter__和next来达到生成迭代器的方法,但写法过于复杂

class Fab(object):     def __init__(self, max):         self.max = max         self.n, self.a, self.b = 0, 0, 1     def __iter__(self):         return self     def next(self):         if self.n < self.max:             r = self.b             self.a, self.b = self.b, self.a + self.b             self.n = self.n + 1             return r         raise StopIteration() >>> for n in Fab(5):  ...     print n  ...  1  1  2  3  5

例四: yield版

和第一版对比仅仅只是把print修改成yield即可.每次执行到yield就return一个生成器.下次再循环时从yiled后面开始执行直到再次执行到yield return一个生成器。

def fab(max):     n, a, b = 0, 0, 1     while n < max:         yield b         a, b = b, a + b         n = n + 1 >>> for n in fab(5):  ...     print n  ...  1  1  2  3  5

另一个yield的例子:

def read_file(fpath):     BLOCK_SIZE = 1024     with open(fpath, 'rb') as f:         while True:             block = f.read(BLOCK_SIZE)             if block:                 yield block             else:                 return

转载于:https://my.oschina.net/u/2474096/blog/824345

你可能感兴趣的文章
ASP.NET MVC 3 Razor Nested foreach with if statements
查看>>
【Mysql】命令行
查看>>
Asterisk 安装与配置
查看>>
利用日志记录所有LINQ的增,删,改解决方案
查看>>
实例讲解PostSharp(一)
查看>>
graylog 客户端的安装配置
查看>>
CentOS6.4_X86_64 安装Drupal-7.31必须成功版!
查看>>
驱动学习之驱动和应用的接口
查看>>
hbase region split源码分析
查看>>
MySQL备份之分库分表备份脚本
查看>>
Java 与 Netty 实现高性能高并发
查看>>
SurfControl人工智能新突破 领跑反垃圾邮件
查看>>
一个动态ACL的案例
查看>>
jquery 表单验证
查看>>
openstack 之 windows server 2008镜像制作
查看>>
VI快捷键攻略
查看>>
Win server 2012 R2 文件服务器--(三)配额限制
查看>>
卓越质量管理成就创新高地 中关村软件园再出发
查看>>
linux rsync 远程同步
查看>>
httpd的manual列目录漏洞
查看>>