Week 4
1 迭代器
1.1 列表生成式
[ i*2 for i in range(10) ]
1.2 迭代器概念
迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值。
直接作用于for循环的对象统称为可迭代对象:Iterable,包括:list
、tuple
、dict
、set
、str
等。内置有__iter__方法,可以使用isintance()判断一个对象是否是Iterable对象。
内置有__iter__又内置有__next__方法的对象称为迭代器:Iterator。
迭代器的优点:
- 提供了一种不依赖于索引的取值方式
- 惰性计算,节省内存
迭代器的缺点:
- 取值不如按照索引取值方便
- 一次性的,只能往后走不能往前退
- 无法获取长度
ps.字符串,列表,元组,字典,集合,文件对象都不是可迭代对象,只不过在for循环式,调用了他们内部的__iter__方法变成可迭代对象,然后for循环调用可迭代对象的__next__方法去取值,而且for循环会捕捉StopIteration异常,以终止迭代。
#得到的迭代器:既有__iter__又有一个__next__方法 d={'a':1,'b':2,'c':3} i=d.__iter__() #i叫迭代器 print(i) print(i.__next__()) print(i.__next__()) print(i.__next__()) print(i.__next__()) #StopIteration
2 生成器
( i*2 for in range(10) ) #generator
generator保存的是算法,只有在调用时才会生成相应的数据。生成器就是迭代器。
generator函数:函数体内包含有yield关键字,该函数执行的结果是生成器。generator函数在每次调用next执行,遇到yield语句返回,再次执行时从上次返回的yield语句继续执行。
def fib(max): n,a,b=0,0,1 while n <max: yield b a,b=b,a+b n+=1 return 'done' data = fib(10) print(data.__next__())
yield的功能:
- 与return类似,都可以返回值,但不一样的地方在于yield返回多次值,而return只能返回一次值;
- 为函数封装好了__iter__和__next__方法,把函数的执行结果做成了迭代器;
- 遵循迭代器的取值方式obj.__next__(),触发的函数的执行,函数暂停与再继续的状态都是由yield保存的。
在for循环调用generator时,取不到generator的return的返回值。想取返回值,捕获StopIteration错误,返回值包括在StopIteration的value中。
def fib(max): n,a,b=0,0,1 while n <max: yield b a,b=b,a+b n+=1 return 'done' data = fib(10) while True: try: k=next(data) print(k) except StopIteration as e: print('Generator return value:', e.value) break
3 协程函数
import time def consumer(name): #消费者 print("%s 准备吃包子啦!" %name) while True: baozi = yield #yield关键字的另外一种使用形式:表达式形式的yield print("包子[%s]来了,被[%s]吃了!" %(baozi,name)) def producer(name): #生产者 c = consumer('A') c2 = consumer('B') #迭代器 c.__next__() #迭代器方法 c2.__next__() print("老子开始准备做包子啦!") for i in range(1,10): time.sleep(1) print("做了2个包子!") c.send(i) c2.send(i) producer('zhouxy')