Python 为什么要用yield
可能听说过,带有 yield 的函数在 Python 中被称之为 generator(生成器),何谓 generator ?我们先抛开 generator,以一个常见的编程题目来展示 yield 的概念。
如何生成斐波那契數列
斐波那契(Fibonacci)數列是一个非常简单的递归数列,除第一个和第二个数外,任意一个数都可由前两个数相加得到。用计算机程序输出斐波那契數列的前 N 个数是一个非常简单的问题,许多初学者都可以轻易写出如下函数:
1. 简单输出斐波那契數列前 N 个数
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
结果没有问题,但有经验的开发者会指出,直接在 fab 函数中用 print 打印数字会导致该函数可复用性较差,因为 fab 函数返回 None,其他函数无法获得该函数生成的数列。要提高 fab 函数的可复用性,最好不要直接打印出数列,而是返回一个 List。以下是 fab 函数改写后的第二个版本:
2. 输出斐波那契數列前 N 个数第二版
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)
可以使用如下方式打印出 fab 函数返回的 List:
1
1
2
3
5
改写后的 fab 函数通过返回 List 能满足复用性的要求,但是更有经验的开发者会指出,该函数在运行中占用的内存会随着参数 max 的增大而增大,如果要控制内存占用,最好不要用 List来保存中间结果,而是通过 iterable 对象来迭代。例如,在 Python2.x 中,代码:
3. 通过 iterable 对象来迭代
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)
Fab 类通过 next() 不断返回数列的下一个数,内存占用始终为常数:
1
1
2
3
5
然而,使用 class 改写的这个版本,代码远远没有第一版的 fab 函数来得简洁。如果我们想要保持第一版 fab 函数的简洁性,同时又要获得 iterable 的效果,yield 就派上用场了
4. 使用 yield 的第四版
def fab(max):
n, a, b = 0, 0, 1
while n < max:
yield b # 使用 yield
# print b
a, b = b, a + b
n = n + 1 for n in fab(5):
print n
简单地讲,yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator,调用 fab(5) 不会执行 fab 函数,而是返回一个 iterable 对象!在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield b 时,fab 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。
Python 为什么要用yield的更多相关文章
- 终结python协程----从yield到actor模型的实现
把应用程序的代码分为多个代码块,正常情况代码自上而下顺序执行.如果代码块A运行过程中,能够切换执行代码块B,又能够从代码块B再切换回去继续执行代码块A,这就实现了协程 我们知道线程的调度(线程上下文切 ...
- Python中生成器和yield语句的用法详解
Python中生成器和yield语句的用法详解 在开始课程之前,我要求学生们填写一份调查表,这个调查表反映了它们对Python中一些概念的理解情况.一些话题("if/else控制流" ...
- Python 生成器与迭代器 yield 案例分析
前几天刚开始看 Python ,后因为项目突然到来,导致Python的学习搁置了几天.然后今天看回Python 发现 Yield 这个忽然想不起是干嘛用的了(所以,好记性不如烂笔头.).然后只能 花点 ...
- python中xrange和yield的用法
相信很多人对xrange和yield都不是很清楚,网上很多文章也是写的云里雾里的,今天我用最简单的例子给大家说下. 说起xrange的时候就一定要提range,其实xrange 用法与 range 完 ...
- 再议Python协程——从yield到asyncio
协程,英文名Coroutine.前面介绍Python的多线程,以及用多线程实现并发(参见这篇文章[浅析Python多线程]),今天介绍的协程也是常用的并发手段.本篇主要内容包含:协程的基本概念.协程库 ...
- 理解Python协程:从yield/send到yield from再到async/await
Python中的协程大概经历了如下三个阶段:1. 最初的生成器变形yield/send2. 引入@asyncio.coroutine和yield from3. 在最近的Python3.5版本中引入as ...
- Python协程笔记 - yield
生成器(yield)作为协程 yield实际上是生成器,在python 2.5中,为生成器增加了.send(value)方法.这样调用者可以使用send方法对生成器发送数据,发送的数据在生成器中会赋值 ...
- python中lambda、yield、map、filter、reduce的使用
1. 匿名函数lambda python中允许使用lambda关键字定义一个匿名函数.所谓的匿名函数就是说使用一次或者几次之后就不再需要的函数,属于"一次性"函数. #例1:求两数 ...
- python函数式编程之yield表达式形式
先来看一个例子 def foo(): print("starting...") while True: res = yield print("res:",res ...
随机推荐
- Unity3D笔记 Collect
一.输入轴 默认输入轴: Horizontal 和 Vertical被映射到w, a, s, d键和方向键 Fire1, Fire2, Fire3被分别映射到Ctrl,Option(Alt)和Comm ...
- HDU-1003 Max Sum(动态规划,最长字段和问题)
Max Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- POJ3150 Candies【差分约束】
During the kindergarten days, flymouse was the monitor of his class. Occasionally the head-teacher b ...
- Ubuntu16.04下安装配置numpy,scipy,matplotlibm,pandas 以及sklearn+深度学习tensorflow配置+Keras2.0.6(非Anaconda环境)
1.ubuntu镜像源准备(防止下载过慢): 参考博文:http://www.cnblogs.com/top5/archive/2009/10/07/1578815.html 步骤如下: 首先,备份一 ...
- MySQL升级方法一
1.在目标服务器上安装新版本的mysql数据库. 1)解压缩新版mysql数据库压缩包并cp到指定目录: [root@faspdev mnt]# tar -zxvf mysql-5.6.24-linu ...
- web前端开发笔记(1)
一.HTML标签书写有哪些规范? 页面编码. 文档声明. 关键字与描述. 行内元素不能包含块级元素. a标签不能嵌套a标签. 标签名和属性必须用小写字母书写,属性必须加引号,标签必须闭合,单标签页必 ...
- MyBatis返回插入的主键ID(Mysql数据库)
1.Java代码: 1.1 entity类: User.java public class User { private int userId; private String userName; pr ...
- 网站编辑须知9个SEO技巧
1. 文章当中最好需要出现一个网站核心关键词所谓的网站核心的关键词就是指与网站内容相关性比较高并且是比较受欢迎的关键词,当然还有相当高的转化率 2. 文章标题当中需要出现关键词.关键字在标题标签< ...
- extjs中的store
1.store中重要的属性和方法 属性:data.proxy.reader.url.root .... 方法:load 2.理解:data--原料,proxy--运输车,reader--加工厂,sto ...
- gh-ost安装
下载 : https://github.com/github/gh-ost/releases/tag/v1.0.28 先安装Go语言: sudo yum install golang 将gh-ost文 ...