一、迭代
1.重复
2.下一次重复是基于上一次结果
二、迭代器
python为了提供一种不依赖于索引的迭代方式,python会为一些对象内置__iter__方法,obj.__iter__称为可迭代的对象,obj.__iter__得到的结果就是迭代器,得到的迭代器既有__iter__,也有一个__next__方法
d={'a':1,'b':2,'c':3} i=d.__iter__() #i叫迭代器 print(i.__next__())
三、迭代器的优缺点
1.优点:
1)提供了一种不依赖于索引的取值方式
2)惰性计算,节省内存
2.缺点
1)取值不如按照索引取值方便
2)一次性的,只能往后走不能往前推
3)无法预知长度
四、生成器
1.生成器函数:函数体内包含有yield关键字,该函数执行的结果是生成器函数
2.生成器就是迭代器
def foo(): print('first---------->') yield 1 print('second---------->') yield 2 print('third---------->') yield 3 print('fouth---------->') g=foo() print(g.__next__()) print(g.__next__()) print(g.__next__()) print(g.__next__())
yield的功能:
1.与return类似,都可以返回值,但不一样的地方在于yield返回多次值,而return只能返回一次
2.为函数封装好了__iter__和__next__方法,吧函数的执行结果做成了迭代器
3.遵循迭代器的取值方式obj.__next__(),触发函数的执行,函数暂停与再继续的状态都是由yield保存
def countdown(n): print('starting countdown') while n > 0: yield n n-=1 print('stop countdown') g=countdown(5) for i in g: print(i)
send的效果:
1.先为暂停位置的yield传一个值,然后yield回吧值赋值给x
2.与next的功能一样
yield的表达式形式应用
#应用:grep -rl 'root' /etc import os def init(func): def wrapper(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return wrapper #阶段一:递归地找文件的绝对路径,把路径发给阶段二 @init def search(target): 'search file abspath' while True: start_path=yield g = os.walk(start_path) for par_dir, _, files in g: # print(par_dir,files) for file in files: file_path = r'%s\%s' % (par_dir, file) target.send(file_path) #阶段二:收到文件路径,打开文件获取获取对象,把文件对象发给阶段三 @init def opener(target): 'get file obj: f=open(filepath)' while True: file_path=yield with open(file_path,encoding='utf-8') as f: target.send((file_path,f)) #阶段三:收到文件对象,for循环读取文件的每一行内容,把每一行内容发给阶段四 @init def cat(target): 'read file' while True: filepath,f=yield for line in f: res=target.send((filepath,line)) if res: break #阶段四:收到一行内容,判断root是否在这一行中,如果在,则把文件名发给阶段五 @init def grep(target,pattern): 'grep function' tag=False while True: filepath,line=yield tag #target.send((filepath,line)) tag=False if pattern in line: target.send(filepath) tag=True #阶段五:收到文件名,打印结果 @init def printer(): 'print function' while True: filename=yield print(filename) start_path1=r'F:python文件day22a' start_path2=r'F:python文件day22a' g=search(opener(cat(grep(printer(),'root')))) # print(g) # g.send(start_path1) g.send(start_path2)