一、生成器
1、定义:
生成器通过生成器函数产生,生成器函数可以通过常规的def语句来定义,但是不用return返回,而是用yield一次返回一个结果,在每个结果之间挂起和继续它们的状态,来自动实现迭代协议。
也就是说,yield是一个语法糖,内部实现支持了迭代器协议,同时yield内部是一个状态机,维护着挂起和继续的状态。
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__())
# for i in g: #obj=g.__iter__() #obj.__next__()
# print(i)
2、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) # 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)
3、yield的表达式形式
send的效果:
a、先为暂停的那个yield位置传值,然后yield会把值赋给x
b、与next的功能一样
4、生成器函数(计时器)
def countdown(n): while n > 0: yield n n-=1 # g=countdown(5) # print(g.__next__()) # print(g.__next__())
5、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 ahspath' while True: start_path=yield g=os.walk(start_path) for par_dir ,_, files in g: 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: file_path,f = yield for line in f: res = target.send((file_path,line)) if res: break #阶段四:收到每一行内容,判断root是否在这一行中,如果在,则把文件名发给阶段五 @init def grep(target,pattern): 'grep function' tag=False while True: file_path,line=yield tag #target.send((filepath,line)) tag=False if pattern in line: target.send(file_path) tag = True #阶段五:收到文件名,打印结果 @init def printer(): 'print function' while True: filename=yield print(filename) start_path1=r'D:\py.code\test' # start_path2=r'D:\py.code\test\test1' g=search(opener(cat(grep(printer(),'root')))) # print(g) g.send(start_path1)
二、列表解析和三元表达式
1、根据已有列表,高效创建新列表的方式。
s='hello' res=[i.upper() for i in s] print(res) # l=[1,31,73,84,57,22] # l_new=[] # for i in l: # if i > 50: # l_new.append(i) # print(l_new) res=[i for i in l if i > 50] print(res)
2、三元表达式
x=2 y=3 if x > y: print(x) else: print(y) res='aaaaa' if x > y else 'bbbbbbb' print(res) def max2(x,y): if x > y: return x else: return y return x if x > y else y print(max2(1,2))