通过上节的学习,我们知道使用列表生成式,可以直接创建一个列表。但是,有些时候,受到内存的限制等实际情况,列表生成式无法满足。比如,一个长度为1000万的列表,普通内存根本就不够,又或者实际处理的过程中,我们只需要访问前面几个元素,那后面的的绝大部分的空间都浪费了。

思路:如果能做到一开始并不是创建完整的list,而是通过定义一种规则的方式,在循环的过程中不断的推算后续的元素,达到使用到哪个元素才生成哪个元素的效果?在Python中,这种机制称为生成器:generator。

创建generator,方法一:

>>> m = (x for x in range(10))
>>> m
<generator object <genexpr> at 0x0376BF00>

观察可知,和列表生成式相比,区别仅仅在于将最外层的[]换成()。请注意,m并不是一个list,而是一个generator。如何打印generator中的每一个元素呢?笨重方法(该方法基本用不到):

>>> next(m)
0
>>> next(m)
1
>>> l = ['hah','hehe']
>>> next(m)
2

中间有个小插曲,随便做了一个操作,紧接着我们又调用next函数,发现结果还是按照算法计算出下一个值。(当生成器没有更多的元素的时候,会抛出StopIteration错误)

方便的取元素方法:因为generator是可迭代对象(从StopIteration错误类型,我们也可以猜测出来),我们可以使用for循环实现取数:

>>> n = (a+b for a in 'abc' for b in 'xyz')
>>> for i in n:
... print(i)
...
ax
ay
az
bx
by
bz
cx
cy
cz

方法二:

如果上述中的推算算法比较复杂,使用方法一无法实现的时候,可以使用函数来实现。比如著名的斐波拉契数列(1,1,2,3,5,8,13,21……除了第一个和第二个数外,任意一个数都是由其前两个数相加的和)。斐波拉契数列使用列表生成式写不出来,可以使用函数把它打印出来:

>>> def fib(max):
... n,a,b = 0,0,1
... while n < max:
... print (b)
... a,b = b,a+b#相当于将一个tuple(b,a+b)赋值给a,b
... n = n + 1
... return
...
>>> fib (6)
1
1
2
3
5
8

其实,上述fib()和generator非常相近了。只需要把print(b)变成yield b 就可以了:

>>> def fib(max):
... n,a,b = 0,0,1
... while n < max:
... yield b
... a,b = b,a+b
... n = n+ 1
... return
...
>>> fib(6)
<generator object fib at 0x037DA120>

这就是定义generator的第二种方法。如果一个函数中包含yield关键字,那么这个函数就不再是普通函数,而是一个generator。两者的执行流程可以这么区别:普通函数是顺序执行,遇到return或者最后一行代码函数就会返回。而generator,在每次调用next()的时候执行,遇到yield语句返回。再次执行的时候,从上次返回的yield语句处继续执行。

使用for循环来迭代:

>>> m = fib(5)
>>> for i in m :
... print(i)
...
1
1
2
3
5

那么如何获取一个generator中的return的值呢?这时必须捕获StopIteration错误,返回值就包含在StopIteration的value中:

>>> def fib(max):
... n ,a,b = 0,0,1
... while n < max:
... yield b
... a,b = b,a+b
... n = n+1
... return 'Over'
...
>>> m = fib(6)
>>> while True:
... try:
... x = next(m)
... print(x)
... except StopIteration as e:
... print(e.value)
... break
...
1
1
2
3
5
8
Over

练习:

杨辉三角:

          1      n=0
/ \      
1 1     n=1
/ \ / \      
1 2 1    n=2
/ \ / \ / \      
1 3 3 1   n=3
/ \ / \ / \ / \    
1 4 6 4 1  n=4
/ \ / \ / \ / \ / \
1 5 10 10 5 1 n=5

杨辉三角,把二项式系数图形化,把组合数内在的一些代数性质直观的从图形中表现出来,是一种离散型的数与形的优美结合。
有如下规律:
1,每行端点和结尾的数为1;
2、每行数左右对称,由1开始逐渐变大;
3、第n行有n项;
4、第n行数字之和为2的n-1次方;
5、第n行的m个数可表示为C(n-1,m-1),即为从n-1个不同元素中取m-1个元素的组合数;
6、第n行的第m个数和n-m+1个数相等,为组合数性质之一;
7、每个数字等于上一行的左右两个数字之和;(利用此性质可写出整个杨辉三角)
8、(a+b)

n

的展开式中的各项系数依次对应杨辉三角的第(n+1)行中的每一项
如果把杨辉三角的每一行看做一个list,试写一个generator,不断输出下一行的list:
>>> def triangle():
... l=[1]
... while True:
... yield l
... l.append(0)
... l= [l[i-1]+l[i] for i in range(len(l))]
...

验证一下:

>>> x = triangle()
>>> next(x)
[1]
>>> next(x)
[1, 1]
>>> next(x)
[1, 2, 1]
>>> next(x)
[1, 3, 3, 1]
>>> next(x)
[1, 4, 6, 4, 1]
>>> next(x)
[1, 5, 10, 10, 5, 1]
>>> next(x)
[1, 6, 15, 20, 15, 6, 1]
>>> next(x)
[1, 7, 21, 35, 35, 21, 7, 1]
>>> next(x)
[1, 8, 28, 56, 70, 56, 28, 8, 1]
>>> next(x)
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
>>> next(x)
[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]
>>> next(x)
[1, 11, 55, 165, 330, 462, 462, 330, 165, 55, 11, 1]
>>> next(x)
[1, 12, 66, 220, 495, 792, 924, 792, 495, 220, 66, 12, 1]

收工!

Python高级特性——生成器(generator)的更多相关文章

  1. Day10 python高级特性-- 生成器 Generator

    列表生成式可以创建列表,但是受内存限制,列表容量时有限的,创建一个巨量元素的列表,不仅占用很大的存储空间,当仅仅访问前几个元素时,后面的绝大多数元素占用的空间都被浪费了. 如果list的元素可以按照算 ...

  2. python高级特性-生成器

    在python中一边循环一边计算的机制成为生成器(generator) 在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行. 生成list > ...

  3. 三、python高级特性(切片、迭代、列表生成器、生成器)

    1.python高级特性 1.1切片 list列表 L=['Mli','add','sal','saoo','Lkkl'] L[0:3]  #即为['Mli','add','sal']  从索引0开始 ...

  4. python高级特性:切片/迭代/列表生成式/生成器

    廖雪峰老师的教程上学来的,地址:python高级特性 下面以几个具体示例演示用法: 一.切片 1.1 利用切片实现trim def trim(s): while s[:1] == " &qu ...

  5. Python高级特性之:List Comprehensions、Generator、Dictionary and set ...

    今天帅气的易哥和大家分享的是Pyton的高级特性,希望大家能和我一起学习这门语言的魅力. Python高级特性之:List Comprehensions.Generator.Dictionary an ...

  6. python高级之生成器&迭代器

    python高级之生成器&迭代器 本机内容 概念梳理 容器 可迭代对象 迭代器 for循环内部实现 生成器 1.概念梳理 容器(container):多个元素组织在一起的数据结构 可迭代对象( ...

  7. 第三篇:python高级之生成器&迭代器

    python高级之生成器&迭代器   python高级之生成器&迭代器 本机内容 概念梳理 容器 可迭代对象 迭代器 for循环内部实现 生成器 1.概念梳理 容器(container ...

  8. Python高级特性(1):Iterators、Generators和itertools(转)

    译文:Python高级特性(1):Iterators.Generators和itertools [译注]:作为一门动态脚本语言,Python 对编程初学者而言很友好,丰富的第三方库能够给使用者带来很大 ...

  9. Python 高级特性介绍 - 迭代的99种姿势 与协程

    Python 高级特性介绍 - 迭代的99种姿势 与协程 引言 写这个笔记记录一下一点点收获 测试环境版本: Python 3.7.4 (default, Sep 28 2019, 16:39:19) ...

随机推荐

  1. 充满含金量的一场云原生Meetup,入场券免费发送中……

    在武汉,你离这场云原生盛会,只有一步之遥 华为云.百度.斗鱼.海云基因,五位重量级专家 K8s调度.深度学习平台.斗鱼实战.基因大数据-五个干货议题 日,与您相约Cloud Native Days C ...

  2. nmon脚本——对Linux服务器的监控

    继服务器被挖之后,我又开拓了另一个监控工具----nmon! Nmon可以很轻松的监控系统的CPU.内存.网络.硬盘.文件系统.NFS.高耗进程.资源和IBM Power系统的微分区的信息,还有专属的 ...

  3. 基于jquery的弹幕实现

    前几天,需要做一个弹幕展示效果,看了网上很多资料,但是很不凑巧,都不能满足自己的需求和功能点,但是总不能放弃吧,那么就自己写一个,今天把成果分享给大家,首先说一下市面上比较流行的弹幕插件吧: 1.有关 ...

  4. 深度学习DeepLearning核心技术理论与实践

    深度学习DeepLearning核心技术开发与应用时间地点:2019年11月01日-04日(北京) 联系人杨老师  电话(同微信)17777853361

  5. NRF5340首款双核处理器无线SoC

    nRF5340基于Nordic经过验证并在全球范围广泛采用的nRF51和nRF52系列多协议SoC而构建,同时引入了具有先进安全功能的全新灵活双处理器硬件架构,支持包括蓝牙5.1/低功耗蓝牙 (Blu ...

  6. CollectionView常用的布局方式总结

    结合网上的collectionView常用布局整合的collectionView使用工具 下载地址 支持五种布局方式ZFCollectionViewLayoutType有两种ZFCollectionV ...

  7. CSS_实现京东购物车静态页面

    主页面分配: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> < ...

  8. Redis 命令执行过程(下)

    在上一篇文章中<Redis 命令执行过程(上)>中,我们首先了解 Redis 命令执行的整体流程,然后细致分析了从 Redis 启动到建立 socket 连接,再到读取 socket 数据 ...

  9. 2019CCPC秦皇岛 E题 Escape(网络流)

    Escape Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Su ...

  10. tensorflow处理mnist(二)

    用卷积神经网络解决mnist的分类问题. 简单的例子 一行一行解释这个代码. 这个不是google官方的例子,但是很简洁,便于入门.tensorflow是先定义模型,最后赋值,计算.为了讨论问题方便, ...