一、生成器
1. 列表生成
>>> [i*2 for i in range(10)] [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] >>> [i for i in range(10)] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
列表生产优点:节约内存,采取边生成边使用元素的模式,使用完了则销毁。而普通的列表,是一次性在内存中创建。
2. 创建第一个生成器 generator
>>> gen = (i*2 for i in range(10)) # 即把列表的[] 改成() >>> for j in gen: ... print(j) ... 0 2 4 6 8 10 12 14 16 18
3. next使用(__next__)
>>> gen = (i*2 for i in range(10)) >>> gen.__next__() 0 >>> gen.__next__() 2 >>> gen.__next__() 4 >>> next(gen) 6
注:如果取完了,则会报错
>>> next(gen) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
4. for循环迭代
>>> gen = (i*2 for i in range(10)) >>> for i in gen: ... print(i) ... 0 2 4 6 8 10 12 14 16 18
5. 生成器保存的是算法,通过算法计算式出下一个值,__next__()
案例:
def fib(max): count, a, b = 0, 0, 1 #1 while count < max: #2 yield b #3 a, b = b, a+b #4 count = count+1 #5 g = fib(6) print(g) # 结果:<generator object fib at 0x0000000000731DB0> for i in g: print(i)
结果:
1 #1-->2-->3 count=0 1 #4-->5--2-->3 count=1 2 #4-->5--2-->3 count=2 3 #4-->5--2-->3 count=3 5 #4-->5--2-->3 count=4 8 #4-->5--2-->3 count=5
使用while循环:
def fib(max): count, a, b = 0, 0, 1 while count < max: yield b a, b = b, a+b count = count+1 g = fib(6) print(g) while True: try: print('value:', g.__next__()) except StopIteration as e: print('except value:', e.value) break
结果:
<generator object fib at 0x0000000001F71DB0> value: 1 value: 1 value: 2 value: 3 value: 5 value: 8 except value: None
6. 通过yield 实现并发
import time def consumer(name): print('%s开始吃水果' % name) while True: fruit = yield print('%s吃了%s水果' % (name, fruit)) def productor(): Sam = consumer('Sam') Jey = consumer('Jey') Sam.__next__() # 是为了让程序走到fruit = yield,准备吃的步骤 Jey.__next__() for i in range(1,4): time.sleep(1) print('开始分发水果.....') Sam.send(i) Jey.send(i) productor()
结果:
Sam开始吃水果 Jey开始吃水果 开始分发水果..... Sam吃了1水果 Jey吃了1水果 开始分发水果..... Sam吃了2水果 Jey吃了2水果 开始分发水果..... Sam吃了3水果 Jey吃了3水果
二、迭代器
1. 可迭代对象 Iterable
----> 字符串、列表、元组、字典、集合 # 不是生成器
----> 生成器,包括带yield的函数
使用isinstance判断是否可迭代对象;
>>> from collections import Iterable >>> isinstance([], Iterable) True >>> isinstance('ggg', Iterable) True >>> isinstance({}, Iterable) True >>> isinstance((i for i in range(3)), Iterable) True
2. 迭代器的定义
可以被next()调用并不断返回下一个值,成为迭代器:Iterator
>>> from collections import Iterator >>> isinstance([], Iterator) False >>> isinstance((i for i in range(3)), Iterator) True
3. 使用iter() 把iterable 变成iterator
>>> from collections import Iterator >>> isinstance(iter([]), Iterator) True >>> isinstance(iter('asd'), Iterator) True