0°

生成器那点事

内容预览:
  • 所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的...~
  • 当然,访问生成器也可以用for循环来访问,如: for n in g:   &nbs...~
  • 函数是顺序执行,遇到return语句或者最后一行函数语句就返回~

始发于微信公众号: Python那些事

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


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


生成器分为两种,生成器表达式和生成器函数。


一、生成器表达式


可以看一下生成器表达式:


g = (x for x in range(10))


是不是感觉很熟悉?没错,将列表的方括号[ ] 改为圆括号( ) 就变成了生成器表达式。


如何访问生成器中的元素呢?最普遍的办法,是通过g.next(),当然,前提是生成器能够生成元素,若没有更多的元素时,抛出StopIteration的错误。


当然,访问生成器也可以用for循环来访问,如:


for n in g:
   print n


二、生成器函数


在函数中如果出现了yield关键字,那么该函数就不再是普通函数,而是生成器函数。当一个生成器函数调用yield,生成器函数的“状态”会被冻结,所有的变量的值会被保留下来,下一行要执行的代码的位置也会被记录,直到再次调用next()。一旦next()再次被调用,生成器函数会从它上次离开的地方开始。


看一个例子,计算斐波那契数列,使用了生成器:


def fib(max):
   n, a, b = 0, 0, 1
   
while n < max:
       yield b
       a, b = b, a + b
       n = n + 1


生成器函数最难理解的就是和普通函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成生成器函数,则在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行


所以,fib(max) 为一个生成器函数,所以可以通过如下方式生成斐波那契数列的前10个元素:


for n in fib(10):
   print n


当然,生成器函数中比较难以理解的还有生成器的send()函数,这个在协程部分会用到,会继续讲解,感兴趣的同学也可以先学习下哦。


今天,你理解生成器的原理和应用了吗?明天就是六一儿童节了,小编提前祝愿大家永远有儿童般的快乐!


以上就是:生成器那点事 的全部内容。

本站部分内容来源于互联网和用户投稿,如有侵权请联系我们删除,谢谢。
Email:[email protected]


0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论