[oldboy-django][5python基础][高级特性]generator生成器
# 生成器基础
- 定义
在循环的时候不断推算下一个元素的值,而不是一下子创建空间存储所有元素,这样节省空间。
并且在适当的条件结束循环,这种一边循环一边计算的机制,称为generator生成器 - 生成器创建方法(两种)
a.将列表生成式的[]改成()-- 称为生成器表达式
- 列表表达式 l = [x**x for x in range()]
- 生成器: g = (x**x for x in range())
b.带yield的函数
-- 当列表生成表达式比较复杂的时候,可以用函数来实现
ps:
range() 和xrange()区别
range()是一个列表,而xrange()是一个生成器
print(range)得到是[,,,,,,,,]
print(xrange)得到的一个生成器对象 range()会在内存中创建10个数字,而xrange不会创建,只有在循环的时候才会创建每个数字 - yield生成器(我简单的将带yield的函数称为yield生成器)
a.自定义一个生成器
def nrange(num):
temp = -
while True:
temp = temp +
if temp >= num:
return
else:
yield temp b. 使用生成器方法(两种)
- next
程序:
g = nrange()
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g)) 程序输出:
Traceback (most recent call last):
File "F:/oldboy/生成器/自定义生成器.py", line , in <module>
print(next(g))
StopIteration 可以看到每次调用next(g),就计算出g的下一个元素的值,
直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。
这种方法不是很好使,而且还没有对异常StopIteration处理。 - for循环
g = nrange()
for num in g:
print(num) 通过for循环来迭代它,并且不需要关心StopIteration的错误。 - yield生成器生命周期
也就是什么时候结束for循环,对函数改造的生成器,当执行到return或者函数最后一条语句时
就结束for循环 - yield生成器和函数不同
如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator;
区别在于:执行流程不一样。
函数是顺序执行,遇到return就返回;而生成器在每次调用next的时候,遇到yield返回,
下次调用next的时候,接着上次的yield次继续执行 # 生成器使用next和send区别
send:
.使用send前必须使用了一次next
.执行g.send()时,会将send函数参数即10视为yield表达式(注意不是yield右侧的表达式)的结果,
然后,程序会继续推进到下一个yield那里,
最后,将yield 右侧的表达式(注意不是yield表达式)的结果作为send()函数的返回值,返回给外界。 next:
.第一次使用Next时,遇到yield返回,并将yield右边表达式的结果作为next的值返回
.之后使用next和send基本一样,不同的是将None作为yield表达式的结果,
然后,程序会继续推进到下一个yield那里,
最后,将yield右侧的表达式结果作为next()函数的返回值,返回给外界 # m = yield value 理解
只要理解一句话m = yield ,是将表达式"yield 5" 的结果返回给m, 而不是5,
而yield 5表达式结果的值和send, next有关。
如果是send(arg)是将arg作为 yield 5表达式结果赋给m
如果是next,是将None作为yield 表达式结果赋给m;
然后程序推进到下一个yield那里
最后,将yield右边(注意右边两字)的表达式“”作为next或者send函数的返回值,返回给外界 # 实例next
# -*- coding: utf- -*-
def f():
print("start")
current = yield "hello"
print('current=', current)
while True:
value = yield "bad"
print("value=",value)
# value = value + 'not' # 此行会报错,因为value会为None, 不能和字符串进行相加 g = f()
s1 = next(g)
print('s1=',s1)
# 第一次Next时,停止在第5行, 将yield右边的表达式(无即None)作为next()的返回值 s2 = next(g)
print('s2=', s2)
# 第二次的next,会将None作为yield表达式" yield hello"的值赋给current, 即current = None
# 然后程序往下执行,遇到yield "bad"停止,将yield右边的表达式"bad"作为第二次next的返回值 s3 = next(g)
print('s3=',s3)
# 第三次next,会将None作为yield表达式”yield bad"的值赋给value, 即value = None,
# 程序往下执行,遇到value = yield "bad"停止,将"bad"作为第三次next的返回值 # 实例send
# -*- coding: utf- -*-
def f():
print("start")
current = yield "hello"
print('current=', current)
while True:
value = yield "bad"
print("value=",value)
# value = value + 'not' # 此行会报错,因为value会为整形, 不能和字符串进行相加
g = f()
s1 = next(g)# 这一步不能少
print(s1)
# 第一次Next时,停止在第5行, 将yield右边的表达式(无即None)作为next()的返回值 s2 =g.send()
print(s2)
# 生成器调用第一次send时,将send参数10代替表达式"yield hello"的值,赋给current,
# 然后程序往下执行,在遇到yield bad停止,将"bad"作为第一次send()函数的返回值返给外界 s3 = g.send()
print(s3)
# 生成器第二次调用send时,将send参数20代替表达式"yield bad"赋给 value
# 程序往下执行,然后遇到yield bad停止,将"bad"作为第二次send()函数的返回值返给外界
[oldboy-django][5python基础][高级特性]generator生成器的更多相关文章
- [oldboy-django][5python基础][高级特性]Iterator迭代器
# 区分可迭代对象iterable, 迭代器iterator, 生成器generator a. iterable 可直接用for循环的对象,都称为可迭代对象, from collections imp ...
- python基础——高级特性
1.切片 切片: >>> L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack'] >>> L[:3] ['Michael ...
- Python学习札记(十八) 高级特性4 生成器
参考:生成器 Note 1.通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的,且容易造成空间浪费.所以,如果列表元素可以按照某种算法推算出来,那我们可以在循环的过程中 ...
- [python学习篇][廖雪峰][1]高级特性--创建生成器 方法1 a = (x for x in range(1,3))
创建一个生成器的方法: for x in range(1,10000000) ,先生成一个列表[1........9999999] 如果我们只想要后面的几个元素,会发现浪费很多空间.所以,如果列表元素 ...
- [python学习篇][廖雪峰][1]高级特性--创建生成器 方法2 yield
def fib(max): n, a, b = 0, 0, 1 while n < max: print b a, b = b, a + b n = n + 1 将print b 改成yield ...
- 三、python高级特性(切片、迭代、列表生成器、生成器)
1.python高级特性 1.1切片 list列表 L=['Mli','add','sal','saoo','Lkkl'] L[0:3] #即为['Mli','add','sal'] 从索引0开始 ...
- Python高级特性(切片,迭代,列表生成式,生成器,迭代器)
掌握了Python的数据类型.语句和函数,基本上就可以编写出很多有用的程序了. 比如构造一个1, 3, 5, 7, ..., 99的列表,可以通过循环实现: L = [] n = 1 while n ...
- python高级特性:切片/迭代/列表生成式/生成器
廖雪峰老师的教程上学来的,地址:python高级特性 下面以几个具体示例演示用法: 一.切片 1.1 利用切片实现trim def trim(s): while s[:1] == " &qu ...
- python的高级特性:切片,迭代,列表生成式,生成器,迭代器
python的高级特性:切片,迭代,列表生成式,生成器,迭代器 #演示切片 k="abcdefghijklmnopqrstuvwxyz" #取前5个元素 k[0:5] k[:5] ...
随机推荐
- 腾讯云服务器手动和自动安装WordPress网站程序
如果我们需要建站的话,对于基础个人网站.博客建站选择基础的1Mbps带宽配置的1GB内存的腾讯云服务器还是够用的,且如果我们需要用来建网站的话可以手工添加程序,以及有些面板,比如宝塔面板是自带CMS程 ...
- 64位系统中为VS2012添加OpenGL工具包
之前一直都是按照网上教程进行的添加,以前使用的系统是32位的,所以一直都没有问题.最近换了64位系统,要使用到OpenGL,于是就又进行了原来的工作,但进行测试时,老是失败: 但是在目录:" ...
- 【mydigitallife.info】如何禁用Aero窗口自动最大化
Go to Control Panel. Click on Ease of Access link or Ease of Access Center icon. Select Change how y ...
- 【51nod1443】路径和树(堆优化dijkstra乱搞)
点此看题面 大致题意:给你一个无向联通图,要求你求出这张图中从u开始的权值和最小的最短路径树的权值之和. 什么是最短路径树? 从\(u\)开始到任意点的最短路径与在原图中相比不变. 题解 既然要求最短 ...
- WQS二分学习笔记
前言 \(WQS\)二分听起来是个很难的算法,其实学起来也并不是那么难. 适用范围 在某些题目中,会对于某个取得越多越优的物品,限定你最多选择\(k\)个,问你能得到的最优答案. 例如这道题目:[CF ...
- 初学树套树:线段树套Treap
前言 树套树是一个十分神奇的算法,种类也有很多:像什么树状数组套主席树.树状数组套值域线段树.\(zkw\)线段树套\(vector\)等等. 不过,像我这么弱,当然只会最经典的 线段树套\(Trea ...
- pandas 常用统计方法
统计方法 pandas 对象有一些统计方法.它们大部分都属于约简和汇总统计,用于从 Series 中提取单个值,或从 DataFrame 的行或列中提取一个 Series. 比如 DataFrame. ...
- 第三篇、Swift基础学习
1.常量与变量 什么是常量和变量 在Swift中规定:在定义一个标识符时必须明确说明该标识符是一个常量还是变量 使用let来定义常量,定义之后不可以修改 使用var来定义变量,定义之后可以修改 变量的 ...
- cf550D. Regular Bridge(构造)
题意 给出一个$k$,构造一个无向图,使得每个点的度数为$k$,且存在一个桥 Sol 神仙题 一篇写的非常好的博客:http://www.cnblogs.com/mangoyang/p/9302269 ...
- MySql学习笔记02
MySql02 复习 数据库相关 连接数据库的命令 mysql -uroot -p 创建数据库 create database db2; 查询所有的数据库 show databases; 查询单个数据 ...