• day14生成器进阶


    1.复习

    # 迭代器和生成器
    # 迭代器:
    # 双下方法 : 很少直接调用的方法。一般情况下,是通过其他语法触发的
    # 可迭代的 —— 可迭代协议 含有__iter__的方法('__iter__' in dir(数据))
    # 可迭代的一定可以被for循环
    # 迭代器协议: 含有__iter__和__next__方法
    # 迭代器一定可迭代,可迭代的通过调用iter()方法就能得到一个迭代器
    # 迭代器的特点:
        # 很方便使用,且只能取所有的数据取一次
        # 节省内存空间
    
    # 生成器
    # 生成器的本质就是迭代器
    # 生成器的表现形式
        # 生成器函数
        # 生成器表达式
    # 生成器函数:
        #含有yield关键字的函数就是生成器函数
        #特点:
            #调用函数的之后函数不执行,返回一个生成器
            #每次调用next方法的时候会取到一个值
            #直到取完最后一个,在执行next会报错
    
    # 写生成器实现:有一个文件,从文件里分段读取内容
    # readline
    # read(10)
    # 在读出来的内容前面加上一个'***',再返回给调用者
    def generator():
        for i in range(20000):
            yield '哇哈哈%s'%i
    #
    g = generator()  #调用生成器函数得到一个生成器
    # print(list(g))
    # ret = g.__next__()     #每一次执行g.__next__就是从生成器中取值,预示着生成器函数中的代码继续执行
    # print(ret)
    num = 0
    for i in g:
        num += 1
        if num > 50:
            break
        print(i)
    
    # 从生成器中取值的几个方法
        # next
        # for
        # 数据类型的强制转换 : 占用内存
    View Code

    2.生成器函数进阶

    # def generator():
    #     print(123)
    #     content = yield 1
    #     print('=======',content)
    #     print(456)
    #     arg = yield 2
    #     ''''''
    #     yield
    # g1 = generator()
    # g2 = generator()
    # g1.__next__()
    # g2.__next__()
    # print('***',generator().__next__())
    # print('***',generator().__next__())
    
    # g = generator()
    # ret = g.__next__()
    # print('***',ret)
    # ret = g.send('hello')   #send的效果和next一样
    # print('***',ret)
    
    #send 获取下一个值的效果和next基本一致
    #只是在获取下一个值的时候,给上一yield的位置传递一个数据
    #使用send的注意事项
        # 第一次使用生成器的时候 是用next获取下一个值
        # 最后一个yield不能接受外部的值
    
    # 获取移动平均值
    # 10 20 30 10
    # 10 15 20 17.5
    # avg = sum/count
    # 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()
    # avg_g.__next__()
    # avg1 = avg_g.send(10)
    # avg1 = avg_g.send(20)
    # print(avg1)
    
    #预激生成器的装饰器
    # def init(func):   #装饰器
    #     def inner(*args,**kwargs):                                    #===>average
    #         g = func(*args,**kwargs)
    #         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
    # def generator():
    #     a = 'abcde'
    #     b = '12345'
    #     for i in a:
    #         yield i
    #     for i in b:
    #         yield i
    # def generator():
    #     a = 'abcde'
    #     b = '12345'
    #     yield from a
    #     yield from b
    #
    # g = generator()
    # for i in g:
    #     print(i)
    
    # send
        # send的作用范围和next一模一样
        # 第一次不能用send
        # 函数中的最后一个yield不能接受新的值
    
    # 计算移动平均值的例子
    # 预激生成器的装饰器的例子
    # yield from
    View Code

    3.生成器表达式

    # 林海峰
    # egon
    # 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)
    
    # print([i*i for i in range(10)])
    
    #生成器表达式
    g = (i for i in range(10))
    print(g)
    # for i in  g:
    #     print(i)
    
    # 括号不一样
    # 返回的值不一样 === 几乎不占用内存
    
    # 老母鸡=('鸡蛋%s'%i for i in range(10))   #生成器表达式
    # print(老母鸡)
    # for 蛋 in 老母鸡:
    #     print(蛋)
    
    # g = (i*i for i in range(10))
    # g.__next__()
    View Code

    4.各种推导式

    #[每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型]    #遍历之后挨个处理
    #[满足条件的元素相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件]   #筛选功能
    
    # #30以内所有能被3整除的数
    # ret = [i for i in range(30) if i%3 == 0]  #完整的列表推导式
    # g = (i for i in range(30) if i%3 == 0)  #完整的列表推导式
    # print(ret)
    #
    # #30以内所有能被3整除的数的平方
    # ret = [i*i for i in (1,2,3,4) if i%3 == 0]
    # 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 = [name for lst in names for name in lst if name.count('e') ==2]
    # ret = (name for lst in names for name in lst if name.count('e') ==2)
    # print(ret)
    
    #字典推导式
    
    
    # 例一:将一个字典的key和value对调
    # mcase = {'a': 10, 'b': 34}
    # #{10:'a' , 34:'b'}
    # 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}
    # print(mcase_frequency)
    
    #集合推导式,自带结果去重功能
    # squared = {x**2 for x in [1, -1, 2]}
    # print(squared)
    
    
    #各种推导式 : 生成器 列表 字典 集合
        #遍历操作
        #筛选操作
    View Code
  • 相关阅读:
    五分钟,让你明白MySQL是怎么选择索引《死磕MySQL系列 六》 咔咔
    MySQL统计总数就用count(*),别花里胡哨的《死磕MySQL系列 十》 咔咔
    C++类型转换:const_cast 和reinterpret_cast
    C++类型转换
    C++中*和&的用法
    CMake简介
    文件和流IO
    字节存储:大端字节和小端字节
    离线的Window 10无法安装.Net Framework 3.5的解决办法
    KeyTool 使用简介
  • 原文地址:https://www.cnblogs.com/xingqisan/p/10712579.html
Copyright © 2020-2023  润新知