• day12-Python运维开发基础(推导式、生成器与生成器函数)


    1. 推导式(列表推导式、集合推导式、字典推导式)

    # ### 推导式 : 通过一行循环判断,遍历出一系列数据的方式是推导式
    """
    推导式一共三种:
        列表推导式,集合推导式,字典推导式
        [val for val in Iterable]
        {val for val in Iterable}
        {a:b for a,b in iterable}
    """
    
    # (1)单循环的推导式
    """[1,2,3,4,5,6,7,8 ...  50]"""
    lst = []
    for i in range(1,51):
        print(i)
        lst.append(i)
    print(lst)
    
    # 改写成推导式
    lst = [val for val in range(1,51)]
    print(lst)
    
    # (2)带有判断条件的单循环推导式 [判断条件只能是单项分支,其他的不可以]
    """[1,2,3,4,5,6,7,8 ...  50] 要所有的偶数"""
    lst = []
    for i in range(1,51):
        if i % 2 == 0:
            lst.append(i)
    print(lst)
    
    # 改写成推导式 
    lst = [i for i in range(1,51) if i % 2 == 0]
    print(lst)
    
    # (3)多循环推导式 "谁❤谁"
    lst1 = ["常远","皮得意","纸质红"]
    lst2 = ["李德亮","林明辉","陈佳琪"]
    lst_new = []
    for i in lst1:
        for j in lst2:
            strvar = i + "" + j
            lst_new.append(strvar)
    print(lst_new)
    
    # 改写成推导式 
    lst = [i + "" + j  for i in lst1 for j in lst2]
    print(lst)
    
    # (4)带有判断条件的多循环推导式
    lst1 = ["常远","皮得意","纸质红"]
    lst2 = ["李德亮","林明辉","陈佳琪"]
    lst_new = []
    for i in lst1:
        for j in lst2:
            if lst1.index(i) == lst2.index(j):
                strvar = i + "" + j
                lst_new.append(strvar)
    print(lst_new)            
    
    # 改写成推导式 
    lst = [i + "" + j for i in lst1 for j in lst2 if lst1.index(i) == lst2.index(j)]
    print(lst)
    推导式 示例代码
    # (1).{'x': 'A', 'y': 'B', 'z': 'C' } 把字典写成x=A,y=B,z=C的列表推导式
    dic = {'x': 'A', 'y': 'B', 'z': 'C' }
    lst = [k+"="+v for k,v in dic.items()]
    print(lst)
    
    # (2).把列表中所有字符变成小写  ["ADDD","dddDD","DDaa","sss"]
    lst = ["ADDD","dddDD","DDaa","sss"]
    lst_new = [i.lower()  for i in lst]
    print(lst_new)
    
    
    # (3).x是0-5之间的偶数,y是0-5之间的奇数 把x,y组成一起变成元组,放到列表当中
    # (0,1) (0,3) (0,5)
    # (2,1) (2,3) (2,5)
    # (4,1) (4,3) (4,5)
    # 方法一
    lst = []
    for i in range(6):
        for j in range(6):
            if i % 2 == 0 and j % 2 == 1:
                res = (i,j)
                lst.append(res)
    print(lst)
    
    # 改写成推导式
    lst = [(i,j) for i in range(6) for j in range(6) if i % 2 == 0 and j % 2 == 1]
    print(lst)
    
    # 方法二
    lst = []
    for i in range(6):
        if i % 2 == 0:
            for j in range(6):
                if j % 2 == 1:
                    res = (i,j)
                    lst.append(res)
    print(lst)
    
    # 改写成推导式
    lst = [(i,j) for i in range(6) if i % 2 == 0 for j in range(6) if j % 2 == 1 ]
    print(lst)
    
    # (4).使用列表推导式 制作所有99乘法表中的运算
    for i in range(1,10):
        for j in range(1,i+1):
            print("%d*%d=%2d " % (i,j,i*j),end="")
            
        print()
            
        
    # 改写成推导式
    lst = ["%d*%d=%2d " % (i,j,i*j) for i in range(1,10) for j in range(1,i+1) ]
    print(lst)
    
    for i in range(9,0,-1):
        for j in range(1,i+1):
            print("%d*%d=%2d " % (i,j,i*j),end="")
            
        print()
    
    # 改写成推导式
    lst = ["%d*%d=%2d " % (i,j,i*j) for i in range(9,0,-1) for j in range(1,i+1) ]
    print(lst)
    
    
    # (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]]
    M = [[1,2,3] , [4,5,6] , [7,8,9]]
    N = [[2,2,2] , [3,3,3] , [4,4,4]]
    
    """
    M[0][0] * N[0][0]  2
    M[0][1] * N[0][1]  4
    M[0][2] * N[0][2]  6
    
    M[1][0] * N[1][0]  12
    M[1][1] * N[1][1]  15
    M[1][2] * N[1][2]  16
    
    M[2][0] * N[2][0]  28
    M[2][1] * N[2][1]  32
    M[2][2] * N[2][2]  36
    """
    # =>实现效果1   [2, 4, 6, 12, 15, 18, 28, 32, 36]
    # lst = [(i,j) for i in range(3) for j in range(3)]
    # print(lst)
    lst = [M[i][j] * N[i][j] for i in range(3) for j in range(3)]
    print(lst)
    
    # =>实现效果2   [[2, 4, 6], [12, 15, 18], [28, 32, 36]]
    # lst = [5 for i in range(3)]
    # lst = [[] for i in range(3)]
    # print(lst)
    
    # lst = [ [(i,j) for j in range(3)] for i in range(3) ]
    lst = [ [ M[i][j]*N[i][j] for j in range(3) ] for i in range(3) ]
    print(lst)
    推导式练习 示例代码
    # ### 集合推导式
    """
    案例:
        满足年龄在18到21,存款大于等于5000 小于等于5500的人,
        开卡格式为:尊贵VIP卡老x(姓氏),否则开卡格式为:抠脚大汉卡老x(姓氏)    
        把开卡的种类统计出来
    """
    listvar = [
        {"name":"王家辉","age":18,"money":10000},
        {"name":"王水机","age":19,"money":5100},
        {"name":"王鹏","age":20,"money":4800},
        {"name":"李站","age":21,"money":2000},
        {"name":"李小龙","age":180,"money":20}
    ]
    
    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)
    
    """三目运算符 :  真区间值 if 条件表达式 else 假区间值"""
    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)enumerate
    """
    enumerate(iterable,[start=0])
    功能:枚举 ; 将索引号和iterable中的值,一个一个拿出来配对组成元组放入迭代器中
    参数:
        iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range) 
        start:  可以选择开始的索引号(默认从0开始索引)
    返回值:迭代器
    """
    from collections import Iterator,Iterable
    # 基本语法
    listvar = ["张龙","余泽民","众赞林"]
    it = enumerate(listvar)
    print(it)
    
    res = isinstance(it,Iterator)
    print(res)
    
    # (1) next
    """
    res = next(it)
    print(res)
    res = next(it)
    print(res)
    res = next(it)
    print(res)
    """
    # for 
    """
    for i in it:
        print(i)
    """
    # for + next 
    """
    for i in range(2):
        res = next(it)
        print(res)
    """
    # list
    """
    lst = list(it)
    print(lst)
    """
    
    # 从5下标开始枚举
    lst= list(   enumerate(listvar,start=5)   )
    print(lst)
    
    
    # 1.转化成字典推导式变成字典
    listvar = ["张龙","余泽民","众赞林"]
    dic = {a:b for a,b in enumerate(listvar) }
    dic = {a:b for a,b in enumerate(listvar,start = 5) }
    print(dic)
    
    # 2.dict 用dict强转迭代器变成字典
    dic = dict( enumerate(listvar ) )
    print(dic)
    
    # (2) zip
    """
    zip(iterable, ... ...)
        功能: 将多个iterable中的值,一个一个拿出来配对组成元组放入迭代器中
        iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range) 
    返回: 迭代器
    多出来无人配对的元素,会自动的舍掉;
    """
    # 基本语法
    lst1 = ["刘守乱","马训","周冰洁"]
    lst2 = ["郭少东","罗启云","尹家平"]
    lst3 = ["郭少东1","罗启云2"]
    it = zip(lst1,lst2,lst3)
    print(isinstance(it , Iterator))
    # 使用list强转迭代器
    lst = list(it)
    print(lst)
    
    # 用zip 形成字典推导式 变成字典
    lst1 = ["a","b","c"]
    lst2 = [1,2,3]
    dic = { k:v for k,v in zip(lst1,lst2) }
    print(dic)
    
    # 用dict 强制转换zip形成的迭代器 变成字典
    dic = dict( zip(lst1,lst2) )
    print(dic)
    
    # 小案例 把dic1中的键和dic2中的值 组合在一起变成新字典;
    dic1 = {"cpx":"身材高大魁梧","zjc":"爱走神","zyl":"活泼好动"}
    dic2 = {"a":"曹培显","b":"主进程","c":"周永玲"}
    container1 = dic1.keys()
    print(container1)
    
    container2 = dic2.values()
    print(container2)
    
    # res = list(  zip(container1,container2)  )
    # print(res)
    
    # 1.通过dict 强制转换变成字典
    dic = dict(   zip(container1,container2)   )
    print(dic )
    
    # 2.使用推导式配合zip 变成字典
    dic = {k:v for k,v in zip(container1,container2)}
    print(dic)
    集合_字典推导式 示例代码

    2. 生成器与生成器函数

     

    # ### 生成器
    """
    #生成器本质是迭代器,允许自定义逻辑的迭代器
    
    #迭代器和生成器区别:
        迭代器本身是系统内置的.重写不了.而生成器是用户自定义的,可以重写迭代逻辑
    
    #生成器可以用两种方式创建:
        (1)生成器表达式  (里面是推导式,外面用圆括号)
        (2)生成器函数    (用def定义,里面含有yield)
    """
    from collections import Iterator , Iterable
    # (1) 生成器表达式 generator 
    gen = ( i for i in range(5) )
    print(gen)
    res = isinstance(gen,Iterator)
    print(res)
    
    # (2) 获取生成器中的数据
    
    # 1. next 
    res = next(gen)
    print(res)
    res = next(gen)
    print(res)
    res = next(gen)
    print(res)
    res = next(gen)
    print(res)
    res = next(gen)
    print(res)
    # res = next(gen) error
    # print(res)
    
    # 2.for
    gen = ( i for i in range(5) )
    for i in gen:
        print(i)
    
    # 3.list
    gen = ( i for i in range(5) )
    lst = list(gen)
    print(lst)
    
    # 4 for + next
    gen = ( i for i in range(5) )
    for i in range(2):
        res = next(gen)
        print(res)
    生成器 示例代码
    # ### 生成器函数
    """
    # yield 类似于 return
    共同点在于:执行到这句话都会把值返回出去
    不同点在于:yield每次返回时,会记住上次离开时执行的位置 , 下次在调用生成器 , 会从上次执行的位置往下走
               而return直接终止函数,每次重头调用.
    yield 6 和 yield(6) 2种写法都可以 yield 6 更像 return 6 的写法 推荐使用
    """
    # (1) 基本语法
    # 生成器函数
    def mygen():
        print("one")
        yield 1
        
        print("two")
        yield 2
        
        print("three")
        yield 3
        
    #  初始化生成器函数 -> 生成器对象 -> 简称生成器
    gen = mygen()
    print(gen)
    
    # 调用生成器
    res = next(gen) # 第一次调用生成器
    print(res)
    
    res = next(gen) # 第二次调用生成器
    print(res)
    
    res = next(gen) # 第三次调用生成器
    print(res)
    
    # res = next(gen) # error # 第四次调用生成器
    # print(res)
    
    """
    初始化生成器函数
    
    第一次调用生成器
    res = next(gen)   print(one)  yield 1 记录当前代码执行的状态,将1返回,返回到调用处,阻塞等待下一次调用
    
    第二次调用生成器
    res = next(gen)   从13行,上一次记录的位置,往下执行 , print(two)  yield 2 记录当前代码执行的状态,将2返回,返回到调用处,阻塞等待下一次调用
    
    第三次调用生成器
    res = next(gen )  从16行,上一次记录的位置,往下执行 , print(three) yield 3 记录当前代码执行的状态,将3返回,返回到调用处,阻塞等待下一次调用
    
    第四次调用生成器
    从19行继续向下执行,发现没有yield 了 ,没有数据可以返回, 直接报错;
    """
    
    # (2) 改造生成器
    def func():
        for i  in range(1,101):
            yield "球衣号码{}".format(i)
            
    # 初始化生成器函数 -> 生成器对象 -> 简称生成器
    gen = func()
    for i in range(50):
        res = next(gen)
        print(res)
    
    for i in range(30):
        res = next(gen)
        print(res)
    
    # (3) send send是把数据发送给上一个yield
    """
    ### send
    # next和send区别:
        next 只能取值
        send 不但能取值,还能发送值
    # send注意点:
        第一个 send 不能给 yield 传值 默认只能写None
        最后一个yield 接受不到send的发送值
    """
    def mygen():
        print("start")
        res1 = yield 1
        print(res1)
        
        res2 = yield 2
        print(res2)
        
        res3 = yield 3
        print(res3)    
        
        print("end")
        
    # 初始化生成器函数 -> 生成器对象 -> 生成器
    gen = mygen()
    # 因为要发送给上一个yield , 第一次发送只能None
    val1 = gen.send(None)
    print(val1)
    
    print("<====>")
    val2 = gen.send("one")
    print(val2)
    
    print("<====>")
    val3 = gen.send("two")
    print(val3)
    
    # 最后一次调用,因为没有yield 直接越界报错
    # val4 = gen.send("three")
    # print(val4)
    """
    val1 = gen.send(None)
    第一次发送 因为要发送给上一个yield ,所以只能是None
    print("start")
    走到 81 行 ,记录当前代码执行的状态,将1返回,val1接受数据,添加阻塞,等待下一次调用
    
    第二次发送
    val2 = gen.send("one") 81行记录的状态往下执行,yield 1 接收到send 发送过来的数据"one" res1 = "one"  print(pme)
    走到 84 行 ,res2 = yield 2 , 记录当前代码执行的状态,将2返回,val2接受数据,添加阻塞,等待下一次调用
    
    第三次发送
    val3 = gen.send("two") 84行记录的状态往下执行, yield 2 接收到send 发送过来的数据"two" res2 = "two" print(two)
    走到 87 行 ,res3 = yield 3,  记录当前代码执行的状态,将3返回,val3接受数据,添加阻塞,等待下一次调用
    
    第四次发送
    从87行往下执行
    print(res3)
    print("end")
    因为没有yield 返回数据, StopIteration 越界错误;    
    """
    
    # (4)yield from : 将一个可迭代对象变成一个迭代器返回    
    def mygen():
        yield from [1,2,3,4]
    gen = mygen()
    res = next(gen)
    print(res)
    res = next(gen)
    print(res)
    
    res = next(gen)
    print(res)
    
    res = next(gen)
    print(res)
    
    
    # (5) 斐波那契数列
    # 1 1 2 3 5 8 13 21 34 55 .... 
    
    # a = 0
    # b = 1
    # a,b = b,a+b
    # print(a,b)
    # a,b = b,a+b
    # print(a,b)
    # a,b = b,a+b
    # print(a,b)
    # a,b = b,a+b
    # print(a,b)
    # a,b = b,a+b
    # print(a,b)
    # a,b = b,a+b
    print("<=====>")
    def myfib(maxlength):
        a,b = 0,1
        i = 0
        while i<maxlength:
            # print(b)
            yield b
            a,b = b,a+b
            i+=1
    # 生成器函数 => 生成器对象
    gen = myfib(10)
    
    # for i in gen:
        # print(i)
    
    for i in range(3):
        res = next(gen)
        print(res)
    生成器函数 示例代码

    day12

  • 相关阅读:
    工作感悟(一)
    laydate组件选择时间段的判断
    Win10下免安装版JDK8环境变量配置
    IDEA中lombok插件的安装
    解决加载WEB页面时,由于JS文件引用过多影响页面打开速度的问题
    Windows环境下的MYSQL5.7配置文件定位
    MYSQL使用source命令,导入SQL文件
    MYSQL5.7生成列简介及创建
    MYSQL慢查询优化方法及优化原则
    批量提取文件夹下所有目录及文件名称
  • 原文地址:https://www.cnblogs.com/reachos/p/12147092.html
Copyright © 2020-2023  润新知