Python高级编程——4.生成器和斐波那契(fibonacci)函数
2017-11-01 12:34
555 查看
一、创建生成器(以快速生成列表为例)
生成器的本质是节约内存。
在python2中的xrange和python3中的range实质上就是一个典型的列表生成器。后面均是以python3为例。range快速生成列表的方法:[x for x in range(num)] / [x+y for x in range(num) for y in range(num)]等
创建生成器:将[ ]换成()后,使得列表的结果不会直接全部输出,而是将其转换成列表生成器,通过next方法将结果依次输出,或for循环方法将结果全部输出。这种方法很大程度了节约了内存空间。在res中实质上保存的是一种算法,(x for x in range(num)) / (x+y for x in range(num) for y in range(num))
二、将函数返回值转换成生成器
比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
1, 1, 2, 3, 5, 8, 13, 21, 34, ...
斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:
定义一个斐波那契函数:
这种方法使得输出结果以列表的显示,解决了输出问题,但是依然还是很占用内存空间
③利用yield关键字,yield关键字加在返回值前,将函数的返回值转换成生成器,使得结果依次输出
一般调用next()方法,在python2 中使用 .__next__()方法,在python3中两种方法都可以使用。但是field是怎样将函数转换成生成器的呢?其实在函数的返回值前增加field关键字之后,在调用函数时,这个函数并没有运行,只有在调用next方法时,函数才会运行,且运行至field终止,第二次调用next方法时,函数从field之后开始执行,为了更清楚地了解field加入后,函数的运行状况,在field second之前增加一行代码:
以上例子充分说明,在第一次调用next(res)方法时,函数运行至yield second终止,再一次调用next()方法时,函数接着yield之后运行。
res为迭代器即generator。
④send关键字在field所在函数中的作用
看以下函数代码,增加一个变量temp,temp=yield即为其赋值为None,运行结果如下:
import time
def test1 ( ):
while True:
print("明明")
yield 0
def test2 ( ):
while True:
print("花花")
yield 0
while True:
res1=test1( )
res2=test2( )
next(res1)
next((res2))
time.sleep(2)
以上代码运行就出现以下结果
明明
花花
明明
花花
明明
花花
明明
花花
明明
花花
“明明”和“花花”几乎同时出现,停顿2s后继续同时出现,这就是field的多任务应用。
总结
生成器是这样一个函数,它记住上一次返回时在函数体中的位置。对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。
生成器不仅“记住”了它数据状态;生成器还“记住”了它在流控制构造(在命令式编程中,这种构造不只是数据值)中的位置。
生成器的特点:
1. 节约内存
2. 迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的
生成器的本质是节约内存。
在python2中的xrange和python3中的range实质上就是一个典型的列表生成器。后面均是以python3为例。range快速生成列表的方法:[x for x in range(num)] / [x+y for x in range(num) for y in range(num)]等
创建生成器:将[ ]换成()后,使得列表的结果不会直接全部输出,而是将其转换成列表生成器,通过next方法将结果依次输出,或for循环方法将结果全部输出。这种方法很大程度了节约了内存空间。在res中实质上保存的是一种算法,(x for x in range(num)) / (x+y for x in range(num) for y in range(num))
二、将函数返回值转换成生成器
比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
1, 1, 2, 3, 5, 8, 13, 21, 34, ...
斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:
定义一个斐波那契函数:
def fibonacci (max): first,second,n = 0,1,0 while n<max: first,second=second,first+second n += 1 print(second) 运行结果为:1,2,3,5,8,13,21,34,55,89 但是若数值较大,则打印比较缓慢,且比较占用内存,在命令行输入后如下图: ②为了解决打印缓慢的问题,可在函数中增加一个全局变量list=[],但是毫无疑问,这是非常占用内存空间的,请看下面的实例:
这种方法使得输出结果以列表的显示,解决了输出问题,但是依然还是很占用内存空间
③利用yield关键字,yield关键字加在返回值前,将函数的返回值转换成生成器,使得结果依次输出
一般调用next()方法,在python2 中使用 .__next__()方法,在python3中两种方法都可以使用。但是field是怎样将函数转换成生成器的呢?其实在函数的返回值前增加field关键字之后,在调用函数时,这个函数并没有运行,只有在调用next方法时,函数才会运行,且运行至field终止,第二次调用next方法时,函数从field之后开始执行,为了更清楚地了解field加入后,函数的运行状况,在field second之前增加一行代码:
print("yield 之前") 在field second之后增加一行代码:
print("yield 之后")运行代码发生如下结果:
以上例子充分说明,在第一次调用next(res)方法时,函数运行至yield second终止,再一次调用next()方法时,函数接着yield之后运行。
res为迭代器即generator。
④send关键字在field所在函数中的作用
看以下函数代码,增加一个变量temp,temp=yield即为其赋值为None,运行结果如下:
此时若执行res.send( ),在括号中给值,这个值就会反向传给temp变量,如下图: 以上例子很好的解释了send在函数转换生成器中的作用,可以反向赋值给函数体的变量,借此改变函数中代码运行顺序。 应用场景如:
def demo( ) : while True: print("*"*50) temp = yield if temp==1: print("增加一个用户") elif temp==2: print("修改用户") elif temp ==3: print("删除用户") print(temp) print("~"*50)
⑤实现多任务模拟多任务(进程,线程,协程)实现方式之一:协程,使得多个任务看似同时进行
import time
def test1 ( ):
while True:
print("明明")
yield 0
def test2 ( ):
while True:
print("花花")
yield 0
while True:
res1=test1( )
res2=test2( )
next(res1)
next((res2))
time.sleep(2)
以上代码运行就出现以下结果
明明
花花
明明
花花
明明
花花
明明
花花
明明
花花
“明明”和“花花”几乎同时出现,停顿2s后继续同时出现,这就是field的多任务应用。
总结
生成器是这样一个函数,它记住上一次返回时在函数体中的位置。对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。
生成器不仅“记住”了它数据状态;生成器还“记住”了它在流控制构造(在命令式编程中,这种构造不只是数据值)中的位置。
生成器的特点:
1. 节约内存
2. 迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的
相关文章推荐
- 用Python实现斐波那契(Fibonacci)函数
- 大话数据结构 code 第四章 04斐波那契函数_Fibonacci
- 用Python实现斐波那契(Fibonacci)函数
- 用Python实现斐波那契(Fibonacci)函数
- 一个求最大公约数的函数、一个求Fibonacci(斐波那契)数列函数
- 解析式/推导式, 生成器 datetime 内建函数
- 斐波那契(Fibonacci)数列测试几种编程语言速度
- python基础----迭代器、生成器、协程函数及应用(面向过程实例)
- 递归求斐波那契(Fibonacci)数列某一位的值
- Uva 11582 Colossal Fibonacci Numbers! 快速幂,斐波那契
- Python的生成器表达式与生成器函数
- Python 用一个生成器函数实现杨辉三角
- hdu 1568(Fibonacci)(就是大数的斐波那契公式)
- 在sqlserver中做fibonacci(斐波那契)规律运算
- 【语言工具】Python闭包,装饰器,生成器,偏函数,函数式编程,lamda,map,reduce,filter
- UVa 10236 - The Fibonacci Primes(斐波那契素数)
- Colossal Fibonacci Numbers! 巨大的斐波那契数 UVA - 11582
- [POJ](3070)Fibonacci ---矩阵快速幂与斐波那契
- acm-C++经典程序训练---斐波那契(Fibonacci)数列
- python函数作用域、迭代器与生成器知识点整理