• 推导式及生成器


     

    1、推导式 (comprehensions)

    # 语法 ---> var for var in iterable
    

      

    1.1 列表推导式

    # res = [var for var in iterable ]
    ​
    # 基本语法
    print([i for i in range(100)])
    ​
    # 单循环 + 判断
    print([i for i in range(100) if i % 2 == 1])
    ​
    # 双循环 + 判断
    lst1 = ["中国","美国","牙买加"]
    lst2 = ["黄种人","白种人","黑种人"]
    ​
    print([i + ":" + j for i in lst1 for j in lst2 if lst1.index(i) == lst2.index(j)])
    

      

    1.1.1 列表推导式练习题

    (1).{'x': 'A', 'y': 'B', 'z': 'C' } 把字典写成x=A,y=B,z=C的列表推导式
    dic = {'x': 'A', 'y': 'B', 'z': 'C' }
    print([ k + "=" + v for k,v in dic.items()])
    ​
    (2).把列表中所有字符变成小写  ["ADDD","dddDD","DDaa","sss"]
    lst = ["ADDD","dddDD","DDaa","sss"]
    print([i.lower() for i in lst])
    ​
    (3).x是0-5之间的偶数,y是0-5之间的奇数 把x,y组成一起变成元组,放到列表当中
    print([(x,y) for x in range(0,5,2) for y in range(1,6,2)])
    ​
    (4).使用列表推导式 制作所有99乘法表中的运算
    print(["{}*{}={:2d}".format(i,j,i*j) for i in range(1,9) for j in range(1,i+1)])
    ​
    (5)#求M,N中矩阵和元素的乘积
    M = [ [1,2,3],[4,5,6],[7,8,9]]
    N = [ [2,2,2],[3,3,3],[4,4,4]]
    =>实现效果1   [2, 4, 6, 12, 15, 18, 28, 32, 36]
    =>实现效果2   [[2, 4, 6], [12, 15, 18], [28, 32, 36]]j
    ​
    res1 = [M[i][j]*N[i][j] for i in range(3) for j in range(3)]
    res2 = [[M[i][j]*N[i][j] for j in range(3) ] for i in range(3)]

     

    1.2 集合推导式

    # res = {var for var in iterable}  ---> 去重,无序 (一般用于统计种类)
    ​
    """
    案例:
        满足年龄在18到21,存款大于等于5000 小于等于5500的人,
        开卡格式为:尊贵VIP卡老x(姓氏),否则开卡格式为:抠脚大汉卡老x(姓氏)  
        把开卡的种类统计出来
    """
    ​
    listvar = [
        {"name":"赵一","age":18,"money":9000},
        {"name":"钱二","age":19,"money":5100},
        {"name":"孙三","age":20,"money":4800},
        {"name":"李四","age":21,"money":2000},
        {"name":"周五","age":18,"money":1480}   ]
    ​
    # 常规写法
    setvar = set()
    for i in listvar:
        if 18 <= i["age"] <= 21 and  5000 <= i["money"] <= 5500:
            res = "尊贵VIP卡老" + i["name"][0]
        else:
            res = "抠脚大汉卡老" + i["name"][0]
        setvar.add(res)
    print(setvar)
    ​
    # 改写成集合推导式 ---> {三元运算符 + 推导式}
    setvar = { "尊贵VIP卡老" + i["name"][0] if 18 <= i["age"] <= 21 and  5000 <= i["money"] <= 5500 else "抠脚大汉卡老" + i["name"][0] for i in listvar }
    print(setvar)
    

      

    1.3 字典推导式

    # {k,v for k,v in iterable}
    # iterable 必须是等长二级容器,且个数为二
    

      

    1.3.1 enumerate ,zip

    # enumerate (iterable,start=0)
    """
    功能:枚举 ---> 将索引号和iterable中的值,一个一个拿出来配对组成元组放入迭代器中
    参数:
        iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range) 
        start:  可以选择开始的索引号(默认从0开始索引)
    返回值:迭代器
    """
    lst = ["赵","钱","孙","李","周","吴","郑","王"]
    res = enumerate(lst,start=1)   # [(1, '赵'),(2, '钱'),(3, '孙'),(4, '李'),(5, '周'),(6, '吴'),(7, '郑'),(8, '王')]
    print(list(res))    
    ​
    # zip (iterable1, iterable2,...)
    """
    功能: 将多个iterable中的值,一个一个拿出来配对组成元组放入迭代器中
        iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range) 
    返回: 迭代器
    特征: 如果找不到对应配对的元素,当前元素会被舍弃
    """
    lst1 = [1,2,3,4,5]
    lst2 = ["赵","钱","孙","李","周","吴","郑","王"]
    print(list(zip(lst1,lst2)))    # [(1, '赵'), (2, '钱'), (3, '孙'), (4, '李'), (5, '周')]
    

      

    1.3.2 字典推导式

    lst1 = [1,2,3,4,5]
    lst2 = ["赵","钱","孙","李","周","吴","郑","王"]
    ​
    # 利用 enumerate 形成字典
    res = { k:v for k,v in enumerate(lst2,start=1)}
    ​
    # 利用 zip 形成字典
    res = { k:v for k,v in zip(lst1,lst2)}
    ​
    # dict 强转字典
    res = dict(enumerate(lst2,start=1))
    res = dict(zip(lst1,lst2))
    

      

    2、生成器 (generator)

    # 生成器本质是迭代器,允许自定义逻辑的迭代器
    # 迭代器和生成器区别:迭代器本身是系统内置的.重写不了.而生成器是用户自定义的,可以重写迭代逻辑
    # 生成器可以用两种方式创建:
        (1)生成器表达式  (里面是推导式,外面用圆括号)
        (2)生成器函数    (用def定义,里面含有yield)
        
        yield 与 return
        共同点于:执行到这句话都会把值返回出去
        不同点: yield 每次返回时,会记住上次离开时执行的位置 , 下次在调用生成器 , 会从上次执行的位置往下走,
                而return直接终止函数,每次重头调用. yield 6 和 yield(6) 2种写法都可以 yield 6 更像 return 6 的写法 推荐使用
    

      

    2.1 生成器函数

    # 定义
    def func()
        print("执行生成器")
        yield 1
        
    # 初始化生成器函数,返回生成器对象,简称生成器
    gen_func = func()
    ​
    # 调用生成器
    res = next(gen_func)         # 执行生成器
    print(res)                   # 打印 yield 返回值
    

      

    2.1.1 生成器函数的应用示例

    def func():
        for i in range(1,101):
            yield "该球衣号码是{}".format(i)
    ​
    # 初始化生成器函数  
    gen_func = func()
    ​
    # 调用生成器 (生成10次)
    for i in range(10):
        res = next(gen_func)
        print(res)
        
    # 再次生成从上一次停止位置开始执行
    res = next(gen_func)
    print(res)
    ​
    # 重置生成器
    gen_func1 = func()
    

      

    2.1.2 send 方法

    """
    next 和 send 区别:
        next 只能取值
        send 不但能取值,还能发送值
    send 注意点:
        第一个 send 不能给 yield 传值 默认只能写None
        最后一个yield 接受不到send的发送值
        send 是给上一个yield发送值
    """
    ​
    # 示例
    def func():
        print("process start")
        
        res = yield 100
        print(res,"内部打印1")
        
        res = yield 200
        print(res,"内部打印2")
        
        res = yield 300
        print(res,"内部打印3")
        
        print("process end")
    ​
    # 初始化生成器函数  
    gen_func = func()
    ​
    # 调用生成器
    res = gen_func.send(None)              #  process start    生成器刚启动,send 无法给上一个 yield 传值
    print(res)                             # 打印第一个 yield 返回值 100
    ​
    res = gen_func.send(500)               # send 将500传给上一个 yield 也就是 res = 500 ,内部打印1
    print(res)                             # 打印第二个 yield 返回值 200
    

      

    2.1.3 yield from 方法

    # 返回值:将一个可迭代对象变成一个迭代器
    def func()
        yield from [i for i in range(10)]
        
    # 初始化生成器函数  
    gen_func = func()
    ​
    # 调用
    for i in gen_func:
        print(i)
    

      

    2.2 生成器表达式

    # (var for var in iterable)
    res = (i for i in range(500))
    print(list(res))
    

      

    3、迭代器调用的方式

    # 方式一 next()   (手动触发,一次取一值)
    # 方式二 __iter__ (解释器自动除发,不推荐使用)
    # 方式三 for      (遍历,当数量大时,需控制好遍历数量)
    # 方式四 强转      (list等)
    

      

     

  • 相关阅读:
    uva514Rails(栈)
    hdu1160FatMouse's Speed
    如何截取整个屏幕
    equals 与==
    (转载)equals与==
    (转载)关于ArrayList的5道面试题
    java的一些程序
    (转载)OSI七层参考模型和TCP/IP四层参考模型
    (转载)算法面试题
    (转载)火车运煤
  • 原文地址:https://www.cnblogs.com/zhoulangshunxinyangfan/p/13360279.html
Copyright © 2020-2023  润新知