您的位置:首页 > 编程语言 > Python开发

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

2017-06-13 10:01 393 查看

生成器

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

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

生成器有两种形式

一种是生成器表达式

一种是生成器函数

生成器表达式:

>>> g = (x*x for x in range(1,10))
>>> g
<generator object <genexpr> at 0x10203de60>


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

>>> 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
处继续往下执行。

>>> g = fib(6)
>>> g
<generator object fib at 0x10223de60>


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

>>> 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 "<stdin>", line 1, in <module>
StopIteration: done


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

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

>>> 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


from collections import Iterator
>>> isinstance((x for x in range(10)),Iterator)
True
>>> isinstance([1,2,3],Iterator)
False


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

>>> g = (x for x in range(10))
>>> g
<generator object <genexpr> at 0x10203deb8>
>>> next(g)
0
>>> next(g)
1
...


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

>>> list = [1,2,3,4,5]
>>> next(list)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'list' object is not an iterator


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


>>> g = [x for x in range(10)]
>>> g
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> newg = iter(g)
>>> newg
<list_iterator object at 0x10209ffd0>


总结:

能使用
for
循环遍历的对象是课迭代对象
Iterable


能使用
next()
进行取值的对象就是迭代器对象
Iterator


list
,
tuple
,
dict
,
set
,
str
等集合数据类型不是迭代器对象
Iterator
但它们是可迭代对象
Iterable
,可以使用
iter()
方法将
Iterable
变成
Iterator
对象
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  python