Python-高级特性-生成器和迭代器

生成器generator

目的:list容量太大占太多内存而操作时却仅仅访问前几个元素,generator可以通过循环不断推算出后面的元素,边循环边计算,节省大量空间;

创建一个generator:

>>>vlist=[a*a for a in range(3)]
>>>vlist
[0,1,4]
>>>vgenerator=(b*b for b in range(3))
>>>vgenerator
<generator object <genexpr> at 0x0000001c9c7702620>

打印generator的值:

>>>next(vgenerator)
0
>>>next(vgenerator)
1
>>>next(vgenerator)
4
>>>for i in vgenerator:
...    print(i)
...
0
1
4

如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现,这是一个generator:


>>>def fib(max):
...     n, a, b = 0, 0, 1
...     while n < max:
...       yield b
...       a, b = b, a + b
...       n = n + 1
...     return 'done'
...

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

>>>def odd():
...    print('step 1')
...    yield 1
...    print('step 2')
...    yield(3)
...    print('step 3')
...    yield(5)
...
调用该generator时,首先要生成一个generator对象,然后用next()函数不断获得下一个返回值:
>>> o = odd()
>>> next(o)
step 1
1
>>> next(o)
step 2
3
>>> next(o)
step 3
5
>>> next(o)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
用for循环调用generator时,发现拿不到generator的return语句的返回值。如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:

>>> g = fib(6)
>>> while True:
...     try:
...         x = next(g)
...         print('g:', x)
...     except StopIteration as e:
...         print('Generator return value:', e.value)
...         break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done
普通函数调用直接返回结果,generator函数的“调用”实际返回一个generator对象。

迭代器

一类是集合数据类型,如list、tuple、dict、set、str等;
一类是generator,包括生成器和带yield的generator function。
这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。

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

>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。例如生成器generator.
可以使用isinstance()判断一个对象是否是Iterator对象:

(将上述代码括号里面的Iterable改为Iterator)
把list、dict、str等Iterable变成Iterator可以使用iter()函数:

>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
Python的迭代器Iterator对象表示的是一个数据流,Iterator对象可以通过next()函数调用并不断返回下一个数据,直到没有下一个数据抛出StopIteration错误,这个数据流可看作有序数列,但我们却不能知道这个有序数列的长度,只能通过next()函数不断计算出所需的下一个数据,甚至可以表示一个无限大的数据流,例如 全体自然数,而list永远不能储存全体自然数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值