Python-生成器

目录:https://www.jianshu.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)

运行结果为:

我们将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 并不会产生交替的效果

你可能感兴趣的:(Python-生成器)