博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
20-python基础9-生成器
阅读量:7123 次
发布时间:2019-06-28

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

1. 概念

  python中的生成器(generator)保存的是算法,只有当真正调用需要的值的时候才会去计算出值。它是一种惰性计算(lazy evaluation)。

 

2.列表生成式

  定义一个列表

a = [0,1,2,3,4,5,6,7,8,9]

除了上面直接定义外,我们还可以使用列表生成式:

a = [i for i in range(10)]print(a)#输出[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

3.生成器

  通过上面的列表生成式,我们可以直接创建一个列表。但是受到内存的限制,列表的容量是有限的。而且如果我们创建了一个包含数百万元素的列表,并且只需要用到前面几个元素,那就有大部分空间浪费了。

  所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断的推算后续的元素?这样就不必创建完整的list,从而节省大量的空间。在pyhong中,一边循环一边计算的机制,称为生成器:generator。

  要创建一个generator有很多种方法,我们可以直接将列表生成式改成生成器:

a = (i for i in range(10))print(a)###结果
at 0x0000024897F6B4C0>

3.1 列表生成式和生成器

a = (i for i in range(100000000))b = [i for i in range(100000000)]

  a的生成时间是瞬时的,并且不会占用什么内存空间。因为生成器根本就没有生成所需的内容,只有在访问的时候才会生成相应的值。

3.2 访问生成器

  • 生成器只保留当前位置的值,直接访问 a[5]是没有值的(报错)
  • 只有一个__next()__方法
  • 只能一个一个取值,并且只能往后取值,不能返回取前面的值

  使用循环来取值:

a = (i for i in range(10))for i in a:    print(i) #输出0123456789

  使用__next()__方法取值:

a = (i for i in range(10))print(a.__next__())print(a.__next__())print(a.__next__())print("插入")print(a.__next__())print(a.__next__()) #输出012插入34 

  每调用一个__next()__方法,我们就能取到一个值,并且我们只能往后取值。生成器能记住当前位置的值,但是并不知道前后位置的值,这也是生成器能够节省内存的原因。只有调用到该位置时才会生成相应的数据。

 

4.yield将函数转换成生成器

  利用列表只能实现一部分的功能,一下复杂的运行就不能通过列表生成式这样的来实现了。但是我们可以将一个函数变成生成器。

斐波那契函数:

def fib(n):    a = 1    b = 1    number = 0    while number < n:        print(b)        a,b = b,a+b        number += 1

将该函数变成生成器只需要将print(b) 改为 yield b

def fib(n):    a = 0    b = 1    number = 0    while number < n:        #print(b)        yield b        a,b = b,a+b        number += 1 f = fib(10)print(f.__next__())print(f.__next__())print(f.__next__())print(f.__next__()) #输出1123

5. 生成器结束

  生成器不会把结果保存在一个系列中,而是保存生成器的状态,在每次进行迭代时返回一个值,直到遇到StopIteration异常结束。

def fib(n):    a = 0    b = 1    number = 0    while number < n:        #print(b)        yield b        a,b = b,a+b        number += 1    return '--done--' f = fib(6)while True:    try:        x = next(f)        print(x)    except StopIteration as e:        print('Generator return value:',e.value)        break #输出112358Generator return value: --done--

 

转载于:https://www.cnblogs.com/NewTaul/p/7049599.html

你可能感兴趣的文章
UIView类的UIViewAnimationWithBlocks扩展 和 使用core an...
查看>>
如何使用UIAutomation进行iOS 自动化测试
查看>>
centos
查看>>
Ubuntu单系统(一):苦难深重的校园网
查看>>
MyBatis 学习笔记一基本对象
查看>>
jenkins pipeline slack
查看>>
CoverFlow效果控件无限循环效果
查看>>
Android Activity生命周期应用 网络设置
查看>>
jenkins + svn + mvn + tomcat搭建CI服务
查看>>
easyui 之 datagrid动态列与列宽自适应
查看>>
jvm运行时数据区域解析
查看>>
spring RestTemplate基本使用与总结
查看>>
【MongoDB 可视化工具Robomongo】下载与安装
查看>>
hadoop 问题
查看>>
android 动画
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
python基础二:之列表
查看>>
Koa 请求日志打点工具
查看>>
革命性新特性 | 单一应用跨多Kubernetes集群的部署与管理
查看>>