zoukankan      html  css  js  c++  java
  • 生成器函数进阶 各种推导式

    先是复习:迭代器和生成器:

    迭代器:
    双下方法 : 很少直接调用的方法。一般情况下,是通过其他语法触发的

    可迭代的 —— 可迭代协议 含有__iter__的方法('__iter__' in dir(数据))
    可迭代的一定可以被for循环

    迭代器协议: 含有__iter__和__next__方法

    迭代器一定可迭代,可迭代的通过调用iter()方法就能得到一个迭代器

    迭代器的特点:
    *很方便使用,且只能取所有的数据取一次
    *节省内存空间

    生成器:
    生成器的本质就是迭代器

    生成器的表现形式
    生成器函数
    生成器表达式

    生成器函数:
    含有yield关键字的函数就是生成器函数
    特点:
    *调用函数的之后函数不执行,返回一个生成器
    *每次调用next方法的时候会取到一个值
    *直到取完最后一个,在执行next会报错

    写生成器实现:有一个文件,从文件里分段读取内容

    readline
    read(10)
    在读出来的内容前面加上一个'***',再返回给调用者
    def generator():
    for i in range(20):
    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
    数据类型的强制转换 : 占用内存

    生成器进阶:
    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不能接受外部的值


    获取移动平均值:
    就是不断输入数字,然后取所有输入数字的平均值。
    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):
            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)

    用yield遍历字符串:

    yield from
    def generator():
        a = 'abcde'
        b = '12345'
        yield from a
        yield from b
    
    g = generator()
    for i in g:
        print(i)

     各种推导式:

    [每一个元素或者是和元素相关的操作 for 元素 in 可迭代数据类型]    #遍历之后挨个处理
    [满足条件的元素相关的操作 for 元素 in 可迭代数据类型 if 元素相关的条件] #筛选功能

    例一:30以内所有能被3整除的数
    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]

       例二: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)
    
    #mcase[k]:k 这个是键值对
    例二:合并大小写对应的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)
    #get出来k的大写和小写的值相加,非常聪明!

    集合推导式

    例:计算列表中每个值的平方,自带去重功能

    squared = {x**2 for x in [1, -1, 2]}
    print(squared)
    # Output: set([1, 4])
  • 相关阅读:
    jq省份城市区街道数据整理成树型json并放到页面供网友选择
    python2爬取国家统计局全国省份城市区街道信息
    mp4视频中插入文字
    wap视频广告遇到的问题
    vscode(Visual Studio Code)中安装Debugger for Chrome插件调试页面
    学习node.js的一些笔记
    gulp打开gbk编码的html文件乱码
    解决[Errno 10048]报错
    MyBatis学习总结(一)
    Java学习之软件安装
  • 原文地址:https://www.cnblogs.com/qunxiadexiaoxiangjiao/p/8184901.html
Copyright © 2011-2022 走看看