生成器
生成器生成的元素不会立即生成,当调用的时候才生成。所以,当要用到的数据是某种算法生成的时就可以使用生成器而不占用大量的空间,速度还很快,缺点是只能使用一次。
>>> a = (i+1 for i in range(10)) >>> a <generator object <genexpr> at 0x000002BD6F607A40> >>> a.__next__() 1 >>> a.__next__() 2 >>> a.__next__()
调用是可以用a.__next__() 或 next(a),当每次这样调用很麻烦,也可以使用for遇见迭代。
>>> a = (i+1 for i in range(10)) >>> for x in a: ... print(x) ... 1 2 3 4 5 6 7 8 9 10
生成器也可以用于函数,是的函数也变成一个生成器,就像并行操作一样。
#!/usr/bin python3.5 #-*- coding:utf-8 -*- ''' @auther: Starry @file: fib.py @time: 18-1-19 下午10:30 ''' def fib(Max): n, a, b = 0, 0, 1 while n < Max: yield b a, b = b, a+b n += 1 return '----stop-----' g = fib(10) while True: try: x = next(g) print('g:',x) except StopIteration as e: print('Generator return value:',e.value) break
由于生产器是当调用时运行,所以就像并行操作一样。
#!/usr/bin python3.5 #-*- coding:utf-8 -*- ''' @auther: Starry @file: 生产器并行.py @time: 18-1-19 下午10:49 ''' import time def cunsumer(name): print('%s 准备吃包子了!'%name) while True: baozi = yield print('包子[%s]来了,被[%s]吃了'%(baozi,name)) c = cunsumer('Starry') c.__next__() c.send('韭菜馅') def producer(name): c = cunsumer('A') c1 = cunsumer('B') c.__next__() c1.__next__() print('开始准备做包子了!') for i in range(10): time.sleep(1) print('做了1个包子,分了两半') c.send(i) c1.send(i) producer("STarry")
迭代器
可以直接作用于for循环的对象称为“可迭代对象“”。Iterable
可以被next()函数调用并不断返回下一个值的对象称为“迭代器”。Iterator
检查是否是“可迭代对象”:
>>> from collections import Iterable >>> >>> print(isinstance([],Iterable)) True >>> print(isinstance({},Iterable)) True >>> print(isinstance((),Iterable)) True >>> print(isinstance('abc',Iterable)) True >>> print(isinstance(10,Iterable)) False
见识是否是“迭代器”:
from collections import Iterator print(isinstance([],Iterator)) print(isinstance((i for i in range(10)),Iterator))