一、生成器的两种形式 1.生成器函数的应用
# def cloth(): # for i in range(100): # yield '衣服%s'%i # # g = cloth() # for i in g: # print(i) # for i in range(100): # print(g.__next__()) # # for i in range(50): # print(g.__next__())
#监听文件末尾追加的例子 # def tail(): # f = open('文件','r',encoding='utf-8') # f.seek(0,2) # while True: # line = f.readline() # if line: # yield line # import time # time.sleep(0.1) # g = tail() # for i in g: # print(i.strip() 注:理解while 循环的最佳方式 就是拆分内部
------------------------------------
# line = f.readline()
# if line:
# yield line
# import time
# time.sleep(0.1)
# line = f.readline()
# if line:
# yield line
# import time
# time.sleep(0.1)
# line = f.readline()
# if line:
# yield line
# import time
# time.sleep(0.1)
------------------------------------
神奇的 send ; 可以向生成器中传值
def func(): print('*'*10) a = yield 5 #深度解析 执行第一个yield a = yield 5 时候 先计算等号右边部分,故返回了5,但是中断了,故等号左边部分没有计算 等下一个send时候开始计 print('a : ',a) 算等号左边,此时send带的参数传进来被a 接受 yield 10 # g = func() # num = g.__next__() # # print(num) # num2 = g.send('alex') # num2 = g.send('aaaa') # print(num2) #从哪一个yield开始接着执行,就把一个值传给了那个yield #send不能用在第一个触发生成器 #生成器函数中有多少个yield就必须有多少个next+send next() = .__next__()=send(None)
生成器的预激装饰器
计算平均值
def init(func): #生成器的预激装饰器 def inner(*args,**kwargs): g = func(*args,**kwargs) #func = averager g.__next__() return g return inner @init def averager(): total = 0.0 count = 0 average = None while True term = yield average total += term count += 1 average = total/count yield average # g_avg = averager() # print(g_avg.send(10)) # print(g_avg.send(30))
魔性小用法:yield from 后边加一个可迭代对象 然后可以将其迭代取出
def func(): a = 'AB' b = 'CD' yield from a # for i in a:yield i yield from b # for i in b:yield i 'A','B','C','D' #返回了4次 g = func() # for i in g: # print(i)
总结:
#生成器函数:生成一个生成器的函数 #生成器的本质参数迭代器 #生成器函数的特点: # 带有yield关键字 # 且调用之后,函数内的代码不执行 #触发执行的方式: #next #send (选会) :send(None) == __next__(),send在next的基础上传一个值到生成器函数内部 #send操作不能用在生成器使用的第一次 #for循环
2 列表推导式、生成器表达式
#列表推导式 # y = [1,2,3,4,5,6,7,8] # x = [1,4,9,16,25,36,49,64] # x = [] # for i in y: # x.append(i*i) # print(x) # x = [i*i for i in y] # print(x) #range(100) # x2 = [i/2 for i in range(100)] # print(x2) #生成器表达式 # x = [i*i for i in y] # print(x) # g = (i*i for i in y) # print(g) # print(list(g)) # for i in g: # print(i) # # l = ['鸡蛋%s'%i for i in range(10)] # print(l) # laomuji = ('鸡蛋%s'%i for i in range(10)) # for egg in laomuji: # print(egg)
15、推导式的扩展:
multiples = [i for i in range(30) if i % 3 is 0] print(multiples) # Output: [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
def squared(x): return x*x multiples = [squared(i) for i in range(30) if i % 3 is 0] print(multiples)
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] print([name for lst in names for name in lst if name.count('e') >= 2]) # 注意遍历顺序,这是实现的关键
mcase = {'a': 10, 'b': 34} mcase_frequency = {mcase[k]: k for k in mcase} print(mcase_frequency)
mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3} mcase_frequency = {k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase.keys()} print(mcase_frequency)
squared = {x**2 for x in [1, -1, 2]} print(squared) # Output: set([1, 4])