Python-生成器

目录://www.greatytc.com/p/863c446364a8

生成器

1、什么是生成器?

Python社区,生成器与迭代器看成一种,生成器的本质就是迭代器

2、生成器和迭代器的区别?

生成器是我们用Python代码构建的数据结构。迭代器都是提供的,或者转换得来的

3、获取生成器的三种方式?

(1) 生成器函数

(2) 生成器表达式

(3) python内置函数或模块

注:(1)和(3)本质是差不多的,(1)是自己写的函数,而(3)是Python内置提供的函数。

4、生成器函数

首先我们先自己定义一个普通函数:

def outer():

    print(123)

    return 111

ret=outer()

print(ret)

运行结果为:

123

111

然后我们再来构建一个生成器

将函数中的return换成yield,这样func就不是函数了,而是一个生成器函数

def outer():

    print(123)

    yield 111

ret=outer()

print(ret)

运行结果为:

<generator object outer at 0x03FA9B40>

我们将return更改为yield后,输出的结果为什么和普通函数的结果不同呢?
 由于函数中存在yield,那么这个函数就是一个生成器函数,我们在执行这个函数的时候是获取这个生成器对象,可以直接执行next()来执行以下生成器。

def outer():

    print(123)

    yield 111

ret=outer()

print(next(ret))

运行结果为:

123

111     

这个时候我们输出的结果就是我们想要的了。当然我们可以写多个yield,一个yield对应一个next。

def outer():

    print(111)  #只是打印输出,并不是取值

    print(222)

    yield  3

    a=1

    b=2

    c=a+b

    print(c)

    yield  4

ret=outer()

print(next(ret))  #取到值3

print(next(ret))  

print(next(ret))      当我们的next多与yield时,运行结果就会报错。

运行结果为:

print(next(ret)) StopIteration 

next超过yield数量,就会报错,与迭代器一样。

5、return和yield区别:

return:函数中只存在一个return结束函数,并且给函数的执行者返回值

yield:只要函数中有yield那么他就是生成器函数而不是函数。生成器函数中可以存在多个yield,yield不会结束生成器函数,一个yield对应一个next。

实例:

我们有一个这样的情景:快过春节了,校长给全校学生准备了新年礼物,但是校长并不知道全校人数,所以他就特别慷慨地准备了5000份,他把所有的礼物都带到了学校。

def outer():

    li= []

    for i in range(1,5001):都放到

        li.append("第{}份礼物".format(i))

    return li

ret=outer()

print(ret)

这样做没有问题,但是我们由于学生没有那么多,只有3000个左右,剩下的2000个礼物,就只能占着一定的空间,放在一边了。如果校长送一个学生买一个礼物,那么这就不会占用太多空间存储了。

def gen_outer():

    for i in range(1,5001):

        yield "第{}份礼物".format(i)

ret=gen_outer()

for i in range(200):

    print(next(ret))

for i in range(200):

    print(next(ret))

这两者的区别:

    第一种是直接把礼物都买了,占用内存。

    第二种是送一个学生买一个礼物,非常的节省内存,而且还可以保留上次的位置。

6、yield from 

首先我们先通过一个程序来说明yield from 的功能。

首先没有yield from 的程序

def outer():

    li=[1,2,3,4,5 ]

    yield  li   

ret=outer()

print(next(ret))

运行结果为:

[1, 2, 3, 4, 5]

有yield from的程序

def outer():

    li=[1,2,3,4,5 ]

    yield from li    #相当于yield1 yield2 ...... #将li这个列表变成了一个迭代器返回

ret=outer()

print(next(ret))

运行结果为:
1

可以发现有了yield from 后将li这个列表变成了一个迭代器返回。它是将列表中的每一个元素返回。

当我们写两个yield from时:

def outer():

    lst1 = ['a','b','c','d']

    lst2 = ['e','f','g','h']

    yield from lst1

    yield from lst2

ret = outer()

for i in range(8):

    print(next(ret))

运行结果为:

a

b

c

d

e

f

g

h

由于yield from 是将列表中的每一个元素返回,所以 如果写两个yield from 并不会产生交替的效果

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 我们知道我们可以用列表储存数据,可是当我们的数据特别大的时候建立一个列表的储存数据就会很占内存的。如通过...
    mysimplebook阅读 253评论 0 0
  • 文章来源:python 生成器和迭代器有这篇就够了 什么是迭代器? 迭代器是访问集合元素的一种方式。迭代器对象从集...
    YYL07阅读 549评论 0 4
  • 生成器 通过列表生成式,我们可以直接创建一个列表。但是受内存限制,列表容量肯定是有限的。 而且,创建一个很多很多元...
    小学弟_阅读 341评论 0 0
  • 迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代...
    Mr_Bluyee阅读 1,005评论 0 1
  • 仅供学习参考,转载请注明出处 生成器 利用迭代器,我们可以在每次迭代获取数据(通过next()方法)时按照特定的规...
    Devops海洋的渔夫阅读 9,207评论 0 10