前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Python】10“生成器和迭代器“

【Python】10“生成器和迭代器“

作者头像
肓己
发布2021-08-12 10:25:29
2760
发布2021-08-12 10:25:29
举报
文章被收录于专栏:linux commands

生成器

生成器:generator,是一种一边循环一边计算的机制,在传统的函数中,我们可能要从一个函数得到数组列表,而内存容量是有限的,计算出的值到达一定数量时,这样执行效率就会大打折扣。

而生成器函数,如果需要根据规则计算得到多个值,则是每次返回一个值,遇到关键字yield后然后返回。能更加有效的利用内存,并且可以让调用者先对前面生成的元素进行操作后再继续执行。

生成器有两种形式

  • 一种是生成器表达式
  • 一种是生成器函数

生成器表达式:

代码语言:javascript
复制
>>> g = (x*x for x in range(1,10))
>>> g
 at 0x10203de60>

生成器函数(斐波拉契数列):

代码语言:javascript
复制
>>> def fib(max):
...     n,a,b = 0,0,1
...     while n < max:
...             yield b
...             a,b = b,a+b
...             n = n + 1
...     return 'done'

只要一个函数中使用了yield关键字,就可以理解为这个函数就是生成器函数,每一次调用这个生成器函数时,执行到yield后进入函数中断状态。此时可以理解为这个生成器函数出于挂起状态,下次再调用这个生成器函数时,从上一次返回的yield处继续往下执行。

代码语言:javascript
复制
>>> g = fib(6)
>>> g
0x10223de60>

变量g是一个generator,存放的是一组数值队列,可以通过next()来取里面的值:

代码语言:javascript
复制
>>> next(g)
1
>>> next(g)
1
>>> next(g)
2
>>> next(g)
3
>>> next(g)
5
>>> next(g)
8
>>> next(g)
Traceback (most recent call last):
  File "", line 1, in <module>
StopIteration: done

每调用一次next(g),就计算出数值队列中的下一个元素,当计算到最后一个元素时的下一个元素时,就会抛出异常。

也可以通过`for...in循环来迭代里面的的数值:

代码语言:javascript
复制
>>> g = fib(6)
>>> for x in g:
...     print(x)
... 
1
1
2
3
5
8

总结: 在一个生成器中,遇到return语句或者执行到函数的最后一行,都会中止迭代并抛出异常StopIteration,如果有return返回值,那么这个返回值就在这个异常的value中,并不作为生成器函数的返回值。

迭代器

在我们已知的数据类型中,可以用for循环遍历的类型有两大类:

一是list,tuple,dict,set,str等集合数据类型 二是生成器类型generator,包括生成器表达式和生成器函数

可以使用isinstance()判断一个对象是否是Iterator

代码语言:javascript
复制
from collections import Iterator
>>> isinstance((x for x in range(10)),Iterator)
True
>>> isinstance([1,2,3],Iterator)
False

能用next()调用的对象就是迭代器对象Iterator,很明显generator就是迭代器对象:

代码语言:javascript
复制
>>> g = (x for x in range(10))
>>> g
 at 0x10203deb8>
>>> next(g)
0
>>> next(g)
1
...

list,tuple,dict,set,str等集合数据类型不能用next()调用,它们不是Iterator,而是Iterable可迭代对象:

代码语言:javascript
复制
>>> list = [1,2,3,4,5]
>>> next(list)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'list' object is not an iterator

当然,我们也可以使用iter()Iterable变成Iterator

代码语言:javascript
复制
>>> g = [x for x in range(10)]
>>> g
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> newg = iter(g)
>>> newg
0x10209ffd0>

总结: 能使用for循环遍历的对象是课迭代对象Iterable 能使用next()进行取值的对象就是迭代器对象Iterator list,tuple,dict,set,str等集合数据类型不是迭代器对象Iterator但它们是可迭代对象Iterable,可以使用iter()方法将Iterable变成Iterator对象

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017/06/13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 生成器
  • 迭代器
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档