生成器

一、什么是生成器

通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

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

二、创建生成器

生成器表达式: 使用尖括号的列表推导式。

生成器函数: 使用yield的函数。

生成器函数yield的作用:

1

类似 return 返回值
2.暂停迭代,直到调用下一个next()方法
3.函数调用时返回生成器对象

生成器函数中返回值的send和next区别:

send可以传递参数作为yield表达式的值,而yield的参数是返回给调用者的值。比如函数中有一个yield赋值,x=yield 1,第一次迭代到这里会返回1,a还没有赋值。第二次迭代时使用.send(10),那么a=10。要注意的是第一次调用时必须是send(None)或者是next(),否则会报TypeError错误。总的来说next()等同于send(None)。示例:

三、生成器函数的几大特性

1、生成器函数包含一个或者多个yield

2、当调用生成器函数时,函数将返回一个对象,但是不会立刻向下执行

3、像__iter__()和__next__()方法等是自动实现的,所以我们可以通过next()方法对对象进行迭代

4、一旦函数被yield,函数会暂停,控制权返回调用者

5、局部变量和它们的状态会被保存,直到下一次调用

6、函数终止的时候,StopIteraion会被自动抛出

四、生成器、迭代器

迭代器持有一个内部状态的字段,用于记录下次迭代返回值,它实现了next和iter方法,迭代器不会一次性把所有元素加载到内存,而是需要的时候才生成返回结果。生成器一定是迭代器, 但是迭代器不一定是生成器。

五、为什么使用生成器

1、更容易使用,代码量较小

2、内存使用更加高效。比如列表是在建立的时候就分配所有的内存空间,而生成器仅仅是需要的时候才使用,更像一个记录

3、代表了一个无限的流。如果我们要读取并使用的内容远远超过内存,但是需要对所有的流中的内容进行处理,那么生成器是一个很好的选择,比如可以让生成器返回当前的处理状态,由于它可以保存状态,那么下一次直接处理即可。

posted @ 2019-08-01 16:06 子鱼珠帘 阅读(...) 评论(...) 编辑 收藏