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

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

一、概述

我们在使用一组数据时,通常会定义一个列表,然后循环里面的元素,但是如果你只需要使用列表中的其中几个元素,其他的元素用不到,这样就会造成内存资源的浪费,所以,生成器登上历史舞台。

生成器的作用:列表的元素按某种算法推算出来,我们在后续的循环中不断推算出后续的元素,在python中,这种一边循环一边计算的机制,称之为生成器(generator)。

二、列表生成器

如何给列表ff中的每个元素加1

a=[0,1,2,3,4,5,6,7,8,9]for index,i in enumerate(a):    a[index]+=1print (a)#结果[1,2, 3, 4, 5, 6, 7, 8, 9, 10]

 方法2:

a=[i+1 for i in range(10)]print(a)

  以上这种就叫列表生成

三、生成器

1、创建生成器

生成一个list

>>> a=[i+1 for i in range(10)]>>> a[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

生成一个generator

>>> b=(i+1 for i in range(10))>>> b
at 0x103ca42a0>

python3是通过__next__()去获得generator的下一个返回值,没有元素时,则会抛出抛出StopIteration的错误 

>>> b.__next__()1>>> b.__next__()2>>> b.__next__()3>>> b.__next__()4>>> b.__next__()5>>> b.__next__()6>>> b.__next__()7>>> b.__next__()8>>> b.__next__()9>>> b.__next__()10>>> b.__next__()  #没有元素时,则会抛出抛出StopIteration的错误Traceback (most recent call last):  File "
", line 1, in
StopIteration

 小结:①generator保存的是算法,每次调用next方法时,就会计算下一个元素的值,直到计算到最后一个元素,如果没有更多元素,则会抛出StopIteration的错误。

    ②generator只记住当前位置,它访问不到当前位置元素之前和之后的元素,只能往后访问元素,不能访问元素之前的元素。

2、用for循环去访问generator中的元素

用next方法去一个一个访问元素实际coding场景不适用,因为generator也是可迭代对象,实际coding使用for循环去访问,不用关心StopIteration错误

>>> c=(i+2 for i in range(10))>>> c
at 0x103ca4318>>>> for i in c: #迭代生成器中的元素 print(i)  

四、函数实现生成器

推算的算法比较复杂,用类似列表生成式的for循环无法实现时,可以使用函数来实现

1、斐波那契数列

实现原理:除第一个和第二个数外,任意一个数都可由前两个数相加得到:1, 1, 2, 3, 5, 8, 13, 21, 34, ...,很明显斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易。

def fibna(max):    n,a,b=0,0,1    while n < max:        print(b)        a,b=b,a+b        n=n+1    return "----done---"fibna(5)

  结果:

11235

 这种逻辑推算非常类似一个生成器(generator),如何把一个函数转换成一个生成器?

2、用yield函数转换为生成器(generator)

def fibna(max):    n,a,b=0,0,1    while n < max:        yield b  # 用yield替换print,把fib函数转化成一个生成器        a,b=b,a+b        n=n+1    return "----done---"f=fibna(5)print(f)

  结果:

 如果一个函数中包含yield关键字,那么这个函数就不是一个普通的函数,而是一个生成器(generator)。

注:

①函数是顺序执行的,遇到return语句或者最后一行函数语句就返回

②变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

def fibna(max):    n,a,b=0,0,1    while n < max:        yield b  # 用yield替换print,把fib函数转化成一个生成器        a,b=b,a+b        n=n+1    return "----done---"f=fibna(5)print(f.__next__())print(f.__next__())print(f.__next__())print("--------------")print(f.__next__())print(f.__next__())#访问的是最后一个元素print(f.__next__()) #没有多余的元素

 结果:

112----------------35Traceback (most recent call last):  File "/Users/bianbian/PycharmProjects/test/test12.py", line 15, in 
print(f.__next__()) #没有多余的元素StopIteration: ----done---  

访问生成器中的元素,不用是连续的,可以中间去执行其他程序。

return在这里的作用:当发生异常时,打印ruturn后面的值。

def fibna(max):    n,a,b=0,0,1    while n < max:        yield b  # 用yield替换print,把fib函数转化成一个生成器        a,b=b,a+b        n=n+1    return "----done---"f=fibna(5)for i in f:    print(i)#结果11235

 可以用for循环访问 

3、异常捕获

def fibna(max):    n,a,b=0,0,1    while n < max:        yield b  # 用yield替换print,把fib函数转化成一个生成器        a,b=b,a+b        n=n+1    return "----done---"f=fibna(5)while True:    try:        x = f.__next__()        print("f:",x)    except StopIteration as e:  #当try中的程序执行错误了,才会执行except下面的代码        print("Generator return value:",e.value)        break

  结果

f: 1f: 1f: 2f: 3f: 5Generator return value: ----done---

  捕获这个StopIteration这个异常,当try中的程序执行错误了,就会执行except下面的代码

五、生成器执行原理

1、执行原理

 

转载于:https://www.cnblogs.com/bianfengjie/p/10844899.html

你可能感兴趣的文章
数组和函数学习。通过函数的形式,对事物的属性和行为进行描述。
查看>>
Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK fla
查看>>
jQuery Ajax 全解析
查看>>
springmvc和struts2的区别
查看>>
[BI项目记]-新任务创建
查看>>
django crm01
查看>>
UIViewController的生命周期及iOS程序执行顺序
查看>>
Code Clean读书笔记
查看>>
C# 32位系统与64位系统调用不同的DLL文件
查看>>
什么时候用removeUnusedSpriteFrames和removeUnusedTextures
查看>>
减而治之
查看>>
前端模块化开发的价值
查看>>
How to Run PowerShell Commands on Remote Computers
查看>>
du熊学斐波那契I
查看>>
RD Client、TeamViewer连接主机
查看>>
又通过一道题目,替换字符串 —— 剑指Offer
查看>>
GAN Generative Adversarial Network 生成式对抗网络-相关内容
查看>>
【转载】程序员的鄙视链
查看>>
python学习笔记3:数指、布尔值与空值
查看>>
centos安装mongodb
查看>>