Python进阶必学:生成器

                                    1

生成器

列表推导式:直接生成列表

在这里插入图片描述

什么是生成器?

通过列表生成式,我们可以直接创建一个列表。

但是,受到内存限制,列表容量肯定是有限的,而且创建一个包含100万个元素的列表,不仅占用很大的存储空间.

如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?

这样就不必创建完整的list,从而节省大量的空间。

在Python中,这种一边循环一边计算的机制,称为生成器:generator

生成器是一个特殊的程序,可以被用作控制循环的迭代行为,python中生成器是迭代器的一种。

使用yield返回值函数,每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器。

生成器类似于返回值为数组的一个函数,这个函数可以接受参数,可以被调用。

但是,不同于一般的函数会一次性返回包括了所有数值的数组,生成器一次只能产生一个值,这样消耗的内存数量将大大减小。

而且允许调用函数可以很快的处理前几个返回值,因此生成器看起来像是一个函数。

但是表现得却像是迭代器python中的生成器要创建一个generator,有很多种方法.

第一种方法很简单,只有把一个列表生成式的[]中括号改为()小括号,就创建一个generator

                                    2

#列表生成式

在这里插入图片描述

#生成器

在这里插入图片描述

结果:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

at 0x000002A4CBF9EBA0>

那么创建lis和generator_ex,的区别是什么呢?

从表面看就是[ ]和(),但是结果却不一样,一个打印出来是列表(因为是列表生成式),而第二个打印出来却是 at 0x000002A4CBF9EBA0>。

那么如何打印出来generator_ex的每一个元素呢?

如果要一个个打印出来,可以通过next()函数获得generator的下一个返回值:

#生成器

在这里插入图片描述

print(next(generator_ex))

print(next(generator_ex))

print(next(generator_ex))

print(next(generator_ex))

print(next(generator_ex))

print(next(generator_ex))

print(next(generator_ex))

print(next(generator_ex))

print(next(generator_ex))

print(next(generator_ex))

结果:

0
1
4
9
16
25
36
49
64
81

Traceback (most recent call last):

File “列表生成式.py”, line 42, in

print(next(generator_ex))

StopIteration

                                    3

大家可以看到,generator保存的是算法,每次调用next(generaotr_ex)就计算出他的下一个元素的值,直到计算出最后一个元素。

没有更多的元素时,抛出StopIteration的错误。

而且上面这样不断调用是一个不好的习惯,正确的方法是使用for循环,因为generator也是可迭代对象:

#生成器
在这里插入图片描述

print(i)

结果:

0
1
4
9
16
25
36
49
64
81

所以我们创建一个generator后,基本上永远不会调用next(),而是通过for循环来迭代,并且不需要关心StopIteration的错误.

generator非常强大,如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。

比如著名的斐波那契数列,除第一个和第二个数外,任何一个数都可以由前两个相加得到:

1,1,2,3,5,8,12,21,34…

斐波那契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:

#fibonacci数列

Python进阶必学:生成器_第1张图片

也就是说上面的函数也可以用generator来实现,上面我们发现,print(b)每次函数运行都要打印,占内存,所以为了不占内存,我们也可以使用生成器,这里叫yield。

如下:

Python进阶必学:生成器_第2张图片

yield函数可以让当前函数停下来,等需要调用的时候再执行,资源消耗最小的。
————————————————————————————————————————————————

请大家尊重原创,如要转载,请注明出处:转载自:柠檬班软件测试 ,谢谢!!
有任何疑问,欢迎加入软件测试交流群:698283649 (加群时,请备注:CSDN )。

你可能感兴趣的:(Python进阶必学:生成器)