PYthon生成器函数和各种推导式

#迭代器和生成器
#双下方法:很少直接调用方法,一般通过其他语法触发
#可迭代的————可迭代协议 含有__iter__方法_'__iter__' in dir(数据)
#可迭代的一定可以被for 循环
#迭代器协议:含有__iter__和__next__方法
#迭代器一定可迭代,可迭代的通过调用Iter()方法就能得到一个迭代器
#节省内存 方便实用

#生成器的本质就是迭代器
#生成器的表现形式
# 生成器函数:含有yeild关键字的函数
#    特点:调用函数的之后函数不执行,返回一个生成器
#          每次调用next方法的时候会取到一个值 直到取完最后一个,在执行next会报错
# 生成器表达式

#写生成器实现 有一个文件,从文件里分段读取内容 readline  read(10)
# 在读出来的内容前面加上一个'***',再返回给调用者
def generator():
    for i in range(20):
        yield 'good study day day up%' % i
g=generator() #调用生成器函数得到一个生成器
list(g)#从生成器取值 占内存
print(list(g))
reg =g._next__() #每一次执行g.__next__就是从生成器取值,预示着生成器函数中的代码继续执行
print(ret)
num =0
for i in g:
    num +=1
    if num>50:
        break
    print(i)
#从生成器取值:1.next 2. for循环 3  数据强制类型的转换:占内存
def generator():
    print(123)
    content =yield 1
    print('=====',content)
    yield 1
    print(456)
    arg=yield 2
    print(789)
    
    yield 
g=generator()
ret=g.__next__()
print('***',ret)
ret=g.__next__()
print('***',ret)
ret =g.send('hello')#和next效果一样
ret =g.send(None)#send获取下一个值和next效果一样,只是在获取下一个值的时候,给上一值yield的位置传递一个数据,
# 使用send注意事项:第一次使用生成器用next获取第一个值,最后一个yield不能接受外部的值
ret=g.__next__()
print('***',ret)#baocuo  

#获取移动平均值
#avg=sum/count
def init(func):#装饰器
    def inner(*args,*kwargs):
        g = fun(*args,**kwargs)
        g.__next__()
        return g
    return inner
@init
def avgage():
    sum=0
    count=0
    avg=0
    while True:
        #num =yield
        num = yield avg
        sum+=num
        count +=1
        avg=sum/count
        #yield avg
        # num = yield avg
avg_g =avgage()
avg_g.__next__()
avg1=avg_g.send(10)
print(avg1)
        
def generator():
    a ='abcde'
    b= '12345'
    yield from a
    yield from b
g = generator()
for i in g:
    print(i)
egg_list=['鸡蛋%s' % i for i in range(10)]#列表推导式
print(egg_list)
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)
g=(i**i for i in range(10))
g.__next__()
[每一个元素 或者是和元素相关的操作 for 元素 in 可迭代数据类型]#遍历之后挨个处理
[满足条件的元素相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件]#筛选功能
#30以内能被3整除的数
ret = [i for i in range(30) if i%3=0] #完整的列表推导式
print(ret)
names=[['tom','bb','ede','cdessw','wede'],\
       ['qwewae','reqwwe','hjyh'.'ytre','kioe']]
ret =[for lst in names for name in lst if name.count('e')==2]#多层嵌套 先for小列表 再 for大列表
print(ret)
#字典推导式
#将一个字典的key和value对调
mcase ={'a':10,'b':34}
mcase_frequency={mcase[k]:k for k in mcase}
print(mcase_frequency)
#合并大小写对应的value值,将k统一成小写
mcase ={'a':10,'b':34,'A':7,'Z':3}
#{'a':10+7,'b':34,'z':3}
mcase_frequency ={k.lower():mcase.get(k.lower(),0) + mcase.get(k.upper(),0) for k in mcase.keys()}
#从for开始看for k in mcase.keys()拿到k  
# 然后再前面k.lower():mcase.get(k.lower(),0) + mcase.get(k.upper(),0)放键值对 
# key=k.lower()  value=mcase.get(k.lower(),0) + mcase.get(k.upper(),0)  字典.get找一个小写的key  
#d={'a':10} print(d.get('b',0) 如果get不到 默认为0
print(mcase_frequency)
#集合推导式  自带结果去重
squared ={x**2 for x in[1,-1,2]}
print(squared)
# 生成器的数据只能取一次,取完就没有呢
# 懒惰下运算,不找他取值,他就不工作

猜你喜欢

转载自blog.csdn.net/weixin_38858860/article/details/89117754