一 什么是迭代
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
# while True: # cmd=input('>>: ') # print(cmd) # l=['a','b','c','d'] # count=0 # while count < len(l): # print(l[count]) # count+=1 # # l=['a','b','c','d'] # for count in range(len(l)): # print(l[count]) # d={'a':1,'b':2,'c':3} # # for k in d: # print(k) |
python为了提供一种不依赖于索引的迭代方式,
python会为一些对象内置__iter__方法
obj.__iter__称为可迭代的对象
迭代器的优点
1:提供了一种不依赖于索引的取值方式
2:惰性计算。节省内存
迭代器的缺点:
1:取值不如按照索引取值方便
2:一次性的。只能往后走不能往前退
3:无法获取长度
1
2
3
|
l = [ 1 , 2 , 3 ] for item in l: #i=l.__iter__() print (item) |
1
2
3
4
5
6
7
8
|
l = [ 'x' , 'y' , 'z' ] # print(l[2]) # print(l[0]) # i=l.__iter__() # print(i.__next__()) # print(i.__next__()) # print(i.__next__()) |
1
2
3
4
5
6
7
8
9
|
#得到的迭代器:既有__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 |
1
2
3
4
5
6
7
8
9
10
11
|
def foo(): print ( 'first------>' ) yield 1 print ( 'second----->' ) yield 2 print ( 'third----->' ) yield 3 print ( 'fouth----->' ) g = foo() |
2、生成器就是迭代器
1
2
3
4
5
6
7
|
# print(g.__next__()) # print(g.__next__()) # print(g.__next__()) # print(g.__next__()) # for i in g: #obj=g.__iter__() #obj.__next__() # print(i) |
3、
yield的功能:
1.与return类似,都可以返回值,但不一样的地方在于yield返回多次值,而return只能返回一次值
2.为函数封装好了__iter__和__next__方法,把函数的执行结果做成了迭代器
3.遵循迭代器的取值方式obj.__next__(),触发的函数的执行,函数暂停与再继续的状态都是由yield保存的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
def countdown(n): print ( 'starting countdown' ) while n > 0 : yield n n - = 1 print ( 'stop countdown' ) g = countdown( 5 ) # print(g) # print(g.__next__()) # print(g.__next__()) # print(g.__next__()) # print(g.__next__()) # print(g.__next__()) # print(g.__next__()) # # for i in g: # print(i) |
例题:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#1 编写 tail -f a.txt |grep 'error' |grep '404'命令,周一默写 import time def tail(filepath,encoding = 'utf-8' ): with open (filepath,encoding = encoding) as f: f.seek( 0 , 2 ) while True : line = f.readline() if line: yield line else : time.sleep( 0.5 ) def grep(lines,pattern): for line in lines: if pattern in line: #print(line) yield line g1 = tail( 'a.txt' ) g2 = grep(g1, 'error' ) g3 = grep(g2, '404' ) for i in g3: print (i) |
总结:
1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退)
2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法)
3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。
4.for循环的本质:循环所有对象,全都是使用迭代器协议。
5.(字符串,列表,元组,字典,集合,文件对象)这些都不是可迭代对象,只不过在for循环式,调用了他们内部的__iter__方法,把他们变成了可迭代对象
然后for循环调用可迭代对象的__next__方法去取值,而且for循环会捕捉StopIteration异常,以终止迭代
6.生成器:可以理解为一种数据类型,这种数据类型自动实现了迭代器协议(其他的数据类型需要调用自己内置的__iter__方法),所以生成器就是可迭代对象
7.可以理解为一种数据类型,这种数据类型自动实现了迭代器协议(其他的数据类型需要调用自己内置的__iter__方法),所以生成器就是可迭代对象
8.为何使用生成器之生成器的优点
Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果。这也是生成器的主要好处。
9.生成器小结:
1).是可迭代对象
2).实现了延迟计算,省内存啊
3).生成器本质和其他的数据类型一样,都是实现了迭代器协议,只不过生成器附加了一个延迟计算省内存的好处,其余的可迭代对象可没有这点好处