Python | Generator和Iteration
2018-04-26 本文已影响27人
Ghibli_Someday
-
生成器
生成器是这样一个函数,它记住上次返回时在函数体中的位置。对生成器函数的第二次(或第 n 次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。
生成器不仅“记住”了它数据状态;还“记住”了它在流控制构造中的位置。
特点:
- 节约内存
- 迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的
创建方法:
1、列表推导式中的[]改成()
>>> g = (i for i in range(30) if i%3 is 0)
>>> next(g)
0
>>> next(g)
3
>>> next(g)
6
>>> next(g)
9
>>> next(g)
12
>>> next(g)
15
>>> next(g)
18
>>> next(g)
21
>>> next(g)
24
>>> next(g)
27
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
generator可以通过next()依次一个个打印结果,但如果计算最后一个结果之后,再次调用会报 StopIteration
2、使用yield
>>> def fib(times):
... n = 0
... a, b = 0, 1
... while n < times:
... yield b
... a ,b = b, a+b
... n += 1
... return 'done'
我们用generator后,一般用for循环来迭代,这样可以防止StopIteration
>>> for x in fib(5):
... print(x)
...
1
1
2
3
5
但发现用for循环,拿不到generator的return语句的返回语句,如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中
>>> g = fib(5)
>>> while True:
... try:
... x = next(g)
... print(x)
... except StopIteration as e:
... print('End of Iteration:%s' % e.value)
... break
...
1
1
2
3
5
End of Iteration:done
-
迭代器
简单定义:可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
- 迭代是访问集合元素的一种形式。
- 迭代器是一个可以记住遍历的位置的对象。
- 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
- 迭代器只能往前不会后退。
-
可迭代对象
- 集合类对象,如list, tuple, dict, set, str
- 生成器
- 用isinstance()判断对象能否迭代
>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance(100, Iterable)
False
-
iter()函数
- 生成器都是Iterator对象,但list、dict、str 虽然是Iterable,却不是Iterator。
- 把list、dict、str等Iterable变成Iterator可以使用iter()函数:
>>> from collections import Iterator
>>> isinstance([], Iterator)
False
>>> isinstance(iter([]), Iterator)
True
>>> isinstance((i for i in range(30)), Iterator)
True
Summary | 小结
- 凡是可作用于for循环的对象都是Iterable类型;
- 凡是可作用于next()函数的对象都是Iterator类型
- 集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。