day14 生成器进阶
#从生成器中取值的几个方法
#next
#for
#数据类型的强制转换:占用内存
def generator():
print(123)
content = yield 1
print('=====',content)
print(456)
yield 2
print(789)
g = generator()
ret = g.__next__()
print('***',ret)
ret = g.send('hello') #send的效果和next一样
print('***',ret)
#send获取下一个值的效果和next基本一致
#只是在获取下一个值得时候,给上一个值得位置传递一个数据
#使用send的注意事项
#第一次使用生成器的时候 必须使用next获取下一个值
#最后一个yield不能接受外部的值
#2.获取移动平均值
#10 20 30 10
#10 15 20 17.5
#avg = sum / count
def average():
sum = 0
count = 0
avg = 0
while 1:
# num = yield
num = yield avg
sum += num
count += 1
avg = sum / count
avg_g = average()
avg_g.__next__()
avg1 = avg_g.send(10)
avg1 = avg_g.send(20)
print(avg1)
#预激生成器的装饰器
def init(func): #装饰器
def inner(*args,**kwargs):
g = func(*args,**kwargs) #g = average()
g.__next__()
return g
return inner
@init
def average():
sum = 0
count = 0
avg = 0
while True:
num = yield avg
sum += num # 10
count += 1 # 1
avg = sum/count
avg_g = average() #===> inner
ret = avg_g.send(10)
print(ret)
ret = avg_g.send(20)
print(ret)
#python 3
#方法1
def generator():
a = 'abcde'
b = '12345'
for i in a:
yield i
for i in b:
yield i
g = generator()
for i in g:
print(i)
#方法2 备注:方法1=方法2
def generator1():
a = 'abcde'
b = '12345'
yield from a #yield from用于获取一个字串中的每一个字符
yield from b
g = generator1()
for i in g:
print(i)
# send
# send的作用范围和next一模一样
# 第一次不能用send
# 函数中的最后一个yield不能接受新的值
# 计算移动平均值的例子
# 预激生成器的装饰器的例子
# yield from
egg_list=['鸡蛋%s' %i for i in range(10)] #列表解析(列表推推导式)
print(egg_list)
# laomuji=('鸡蛋%s' %i for i in range(10))#生成器表达式
# print(laomuji)
# print(next(laomuji)) #next本质就是调用__next__
# print(laomuji.__next__())
# print(next(laomuji))
egg_list = []
for i in range(10):
egg_list.append('鸡蛋%s'%i)
print(egg_list)
# #生成器表达式
g = (i for i in range(10))
print(g)
for i in g:
print(i)
# #列表推导式和生成器表达式不同点
# #括号不一样
# #返回值不一样 ===生成器表达式几乎不占用内存
#range(10)里的每一个数字取平方,然后组成一个新的生成器
g = (i*i for i in range(10))
print(g)
for i in g:
print(i)
#[每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型] #遍历之后挨个处理
#[满足条件的元素相关的操作 for 元素 if 元素相关的条件] #筛选功能
#列表推导式
#30以内所有能被3整除的数
ret = [i for i in range(30) if i % 3 == 0] #完整的列表推导式
print(ret)
#30以内所有能被3整除的数的平方
ret = [i*i for i in range(30) if i % 3 == 0] #完整的列表推导式
print(ret)
#找到嵌套列表中名字含有两个'e'的所有名字
names = [['Tom','Billy','Jefferson','Andrew','Wesley','Steven','Joe'],
['Alice','Jill','Ana','Wendy','Jennifer','Sherry','Eva']]
ret = [i for lst in names for i in lst if i.count('e') == 2]
print(ret)
#字典推导式
#将一个字典的key和value对调
mease = {'a':10,'b':30}
f = {mease[k]:k for k in mease}
print(f)
#合并大小写对应的value值,将k统一成小写
mease = {'a':10,'b':34,'A':7,'Z':3}
g = {k.lower():mease.get(k.lower(),0)+mease.get(k.upper(),0) for k in mease.keys()}
print(g)
#集合推导式
#计算列表中每个值得平方,自带去重功能
squared = {x**2 for x in [1,-1,2]}
print(squared)
#各种推导式 生成器 列表 字典 集合
#遍历操作
#筛选操作
'''练习题:
例1: 过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
例2: 求(x,y)其中x是0-5之间的偶数,y是0-5之间的奇数组成的元祖列表
例3: 求M中3,6,9组成的列表M = [[1,2,3],[4,5,6],[7,8,9]]'''
names=['dssd','d','e','dd']
print([name.upper() for name in names if len(name)<3] )
print({(x,y) for x in range(5) if x % 2 ==0 for y in range(5) if y %2==1})
M = [[1,2,3],[4,5,6],[7,8,9]]
print([row[2] for row in M] )