day14 生成器的进阶

一、生成器的两种形式  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)
30以内被3整除的数
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])  # 注意遍历顺序,这是实现的关键
查找名字中含有两个e的
mcase = {'a': 10, 'b': 34}
mcase_frequency = {mcase[k]: k for k in mcase}
print(mcase_frequency)
k和vaule对调
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)
合并大小写对应的value值,将k统一成小写
squared = {x**2 for x in [1, -1, 2]}
print(squared)
# Output: set([1, 4])
计算列表中每个值的平方,自带去重功能

 

 

 

posted on 2017-11-06 19:50  心如沚水  阅读(175)  评论(0编辑  收藏  举报