温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Python全栈推导式和生成器怎么实现

发布时间:2021-12-02 18:50:48 来源:亿速云 阅读:146 作者:iii 栏目:开发技术

本篇内容主要讲解“Python全栈推导式和生成器怎么实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python全栈推导式和生成器怎么实现”吧!

    1. 推导式

    # ### 推导式 : 通过一行循环判断遍历出一些列数据的方法叫做推导式
    """
    语法:
        val for val in iterable
    """
    # 1.推导式基本语法
    lst = []
    for i in range(1,51):
        lst.append(i)
    print(lst)
    # 改写推导式
    lst = [  i for i in range(1,51)  ]
    print(lst)
    # 小练习
    # 1.[1,2,3,4,5] => [2,4,6,8,10]
    lst = [ i*2 for i in range(1,6) ]
    print(lst)
    # 2.带有判断条件的推导式
    """注意点:for后面紧跟的判断条件只能是单项分支."""
    """[1,2,3,4,5,6,7,8,9,10] => [1,3,5,7,9 ... ]"""
    lst = [1,2,3,4,5,6,7,8,9,10]
    lst_new = []
    for i in lst:
        if i % 2 == 1:
            lst_new.append(i)
    print(lst_new)
    # 改写推导式
    lst = [ i for i in lst if i % 2 == 1 ]
    print(lst)
    # 3.多循环推导式 # 谁♡♢♤♠谁
    lst1 = ["孙杰龙","陈露","曹静怡"]
    lst2 = ["王志国","邓鹏","合理"]
    lst_new = []
    for i in lst1:
        for j in lst2:
            lst_new.append(i+"♡♢♤♠"+j)
    print(lst_new)
    # 改写推导式
    lst = [ i+"♡♢♤♠"+j for i in lst1 for j in lst2 ]
    print(lst)
    # 4.带有判断条件的多循环推导式
    lst_new = []
    for i in lst1:
        for j in lst2:
            if lst1.index(i) == lst2.index(j):
                lst_new.append(i+"♡♢♤♠"+j)
    print(lst_new)
    # 改写推导式
    lst = [i+"♡♢♤♠"+j for i in lst1 for j in lst2 if lst1.index(i) == lst2.index(j)]
    print(lst)

    2. 推导式练习

    # ### 推导式练习题
    # (1).{'x': 'A', 'y': 'B', 'z': 'C' } 把字典写成x=A,y=B,z=C的列表推导式
    dic = {'x': 'A', 'y': 'B', 'z': 'C' } 
    lst = []
    for k,v in dic.items():
        res = k + "=" + v
        lst.append(res)
    print(lst)
    # 推导式
    lst = [  k + "=" + v for k,v in dic.items()  ]
    print(lst)
    # (2).把列表中所有字符变成小写  ["ADDD","dddDD","DDaa","sss"]
    lst = ["ADDD","dddDD","DDaa","sss"]
    lst_new = []
    for i in lst:
        lst_new.append(i.lower())
    print(lst_new)
    # 推导式
    lst = [ i.lower() for i in lst ]
    print(lst)
    # (3).x是0-5之间的偶数,y是0-5之间的奇数 把x,y组成一起变成元组,放到列表当中
    # 方法一
    lst = []
    for x in range(6):
        for y in range(6):
            if x % 2 == 0 and y % 2 == 1:
                lst.append( (x,y) )
    print(lst)
    # 推导式
    lst = [ (x,y) for x in range(6) for y in range(6) if x % 2 == 0 and y % 2 == 1 ]
    print(lst)
    
    # 方法二
    lst = []
    for x in range(6):
        if x % 2 == 0 :
            for y in range(6):
                if y % 2 == 1:
                    lst.append( (x,y)  )
    print(lst)
    # 推导式
    lst = [ (x,y) for x in range(6) if x % 2 == 0 for y in range(6) if y % 2 == 1 ]
    print(lst)
    # (4).使用列表推导式 制作所有99乘法表中的运算
    for i in range(1,10):
        for j in range(1,i+1):
            print("{:d}*{:d}={:2d} ".format(i,j,i*j) , end="")
        print()
    lst = ["{:d}*{:d}={:2d} ".format(i,j,i*j) for i in range(1,10) 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]  ] 
    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] = 18
    M[2][0] * N[2][0] = 12
    M[2][1] * N[2][1] = 15
    M[2][2] * N[2][2] = 18
    """
    # =>实现效果1   [2, 4, 6, 12, 15, 18, 28, 32, 36]
    """双层循环,外层循环动的慢,内层循环动的快,正好符号M N 矩阵的下标"""
    lst = []
    for i in range(3):
        for j in range(3):
            lst.append(  M[i][j] * N[i][j]   )
    print(lst)
    
    # =>实现效果2   [  [2, 4, 6], [12, 15, 18], [28, 32, 36]   ]
    # 遍历出三个空的列表
    lst = [ [] for i in range(3)]
    print(lst)
    lst = [    [  M[i][j] * N[i][j] for j in range(3)  ]    for i in range(3)]
    print(lst)
    """
    [  M[i][j] * N[i][j] for j in range(3)  ] 
    [ [2, 4, 6]  [12, 15, 18]  [28, 32, 36] ]
    """

    3. 集合_字典推导式

    # ### 集合推导式
    """
    案例:
    	满足年龄在18到21,存款大于等于5000 小于等于5500的人,
    	开卡格式为:尊贵VIP卡老x(姓氏),否则开卡格式为:抠脚大汉卡老x(姓氏)	
    	把开卡的种类统计出来
    """
    lst = [
        {"name":"赵沈阳","age":18,"money":3000},
        {"name":"赵万里","age":19,"money":5200},
        {"name":"赵蜂拥","age":20,"money":100000},
        {"name":"赵世超","age":21,"money":1000},
        {"name":"王志国","age":18,"money":5500},
        {"name":"王永飞","age":99,"money":5500}
    ]
    setvar = set()
    for i in lst:
        print(i) # {'name': '赵沈阳', 'age': 18, 'money': 3000}
        if 18 <= i["age"] <= 21 and 5000 <= i["money"] <= 5500:
            res = "尊贵VIP卡老{}".format(i["name"][0])
        else:
            res = "抠脚大汉卡老{}".format(i["name"][0])
        # 添加到集合中
        setvar.add(res)
    print(setvar)
    # { 三元运算符 + 推导式 }
    #                                                                                                                                     三运运算符 + 推导式
    setvar = { "尊贵VIP卡老{}".format(i["name"][0]) if 18 <= i["age"] <= 21 and 5000 <= i["money"] <= 5500 else "抠脚大汉卡老{}".format(i["name"][0]) for i in lst }
    print(setvar)
    # ### 字典推导式
    ### 一.enumerate
    """
    enumerate(iterable,[start=0])
    功能:枚举 ; 将索引号和iterable中的值,一个一个拿出来配对组成元组,通过迭代器返回
    参数:
        iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range) 
        start:  可以选择开始的索引号(默认从0开始索引)
    返回值:迭代器
    """
    # 基本语法
    from collections import Iterator,Iterable
    lst =["王文","吕洞宾","何仙姑","铁拐李","张国老","曹国舅","蓝采和","韩湘子"]
    it = enumerate(lst)
    it = enumerate(lst,start=100)
    print(isinstance(it,Iterator))
    # next 
    print( next(it) )
    # for + next (推荐,数据较大时使用)
    for i in range(3):
        print(next(it))
    # for
    for i in it:
        print(i)
    # list 强转迭代器
    print(list(it))
    # (1) 字典推导式 配合 enumerate 来实现
    dic = {k:v for k,v in enumerate(lst,start=100)}
    print(dic)
    """
    (100, '王文')
    (101, '吕洞宾')
    (102, '何仙姑')
    (103, '铁拐李')
    (104, '张国老')
    (105, '曹国舅')
    (106, '蓝采和')
    (107, '韩湘子')
    """
    # (2) 使用dict强转迭代器,瞬间得到字典
    dic = dict( enumerate(lst,start=100) )
    print(dic)
    ### 二.zip
    """
    特点:按照索引配对
    zip(iterable, ... ...)
        功能: 将多个iterable中的值,一个一个拿出来配对组成元组,通过迭代器返回
        iterable: 可迭代性数据 (常用:迭代器,容器类型数据,可迭代对象range) 
    返回: 迭代器
    """
    # 基本语法
    # lst1 = ["孙开启","王永飞","于朝志"]
    # lst2 = ["薛宇健","韩瑞晓","上朝气"]
    # lst3 = ["刘文博","历史园","张光旭"]
    # 在索引下标同时存在时,才会进行配对,否则舍弃.
    lst1 = ["孙开启","王永飞","于朝志"]
    lst2 = ["薛宇健","韩瑞晓"]
    lst3 = ["刘文博"]
    it = zip(lst1,lst2,lst3)
    print(list(it))
    # (1) 字典推导式 配合 zip 来实现
    lst_key = ["ww","axd","yyt"]
    lst_val = ["王维","安晓东","杨元涛"]
    # ('ww', '王维'), ('axd', '安晓东'), ('yyt', '杨元涛')
    dic = {k:v   for k,v in zip(lst_key , lst_val) }
    print(dic)
    # (2) 使用dict强转迭代器,瞬间得到字典
    dic = dict( zip(lst_key , lst_val) )
    print(dic)

    4. 生成器

    4.1 生成器表达式

    # ### 生成器
    """
    #生成器本质是迭代器,允许自定义逻辑的迭代器
    #迭代器和生成器区别:
    	迭代器本身是系统内置的.重写不了.
        而生成器是用户自定义的,可以重写迭代逻辑
    #生成器可以用两种方式创建:
        (1)生成器表达式  (里面是推导式,外面用圆括号)
        (2)生成器函数    (用def定义,里面含有yield)
    """
    # (1) 生成器表达式 (里面是推导式,外面用圆括号)
    gen = ( i for i in range(10) )
    print(gen)
    # 判断类型
    from collections import Iterator,Iterable
    print(isinstance(gen,Iterator))
    # 1.next 调用生成器
    print(next(gen))
    print(next(gen))
    # 2.for + next 调用生成器
    for i in range(3):
        print(next(gen))
    # 3.for 调用生成器所有数据
    for i in gen:
        print(i)
    # 4.list强转生成器,瞬间得到所有数据
    gen = ( i for i in range(10) )
    print(list(gen))
    # print(next(gen)) error  # StopIteration

    4.2 生成器函数

    # ### 生成器函数
    """
    # yield 类似于 return
    共同点在于:执行到这句话都会把值返回出去
    不同点在于:yield每次返回时,会记住上次离开时执行的位置 , 下次在调用生成器 , 会从上次执行的位置往下走
    		   而return直接终止函数,每次重头调用.
    yield 6 和 yield(6) 2种写法都可以 yield 6 更像 return 6 的写法 推荐使用
    """
    # (1) 基本语法
    def mygen():
        print("111")
        yield 1
        print("222")
        yield 2
        print("333")
        yield 3
    # 初始化生成器函数  => 返回生成器对象 => 简称生成器
    gen = mygen()
    # 第一次调用
    res = next(gen)
    print(res)
    # 第二次调用
    res = next(gen)
    print(res)
    # 第三次调用
    res = next(gen)
    print(res)
    # 第四次调用
    """
    StopIteration error 
    res = next(gen)
    print(res)
    """
    """
    # 第一次调用
    print("111")  yield 1 保存当前第13行代码的状态,把1返回,并且等待下一次调用
    # 第二次调用
    从上一次保存的位置13行往下走, print("222") yield 2 保存当前第16行代码的状态,把2返回,并且等待下一次调用
    # 第三次调用
    从上一次保存的位置16行往下走, print("333") yield 3 保存当前第19行代码的状态,把3返回,并且等待下一次调用
    # 第四次调用
    因为没有更多的yield 返回数据,所有停止迭代.出现报错异常.
    """
    # (2) 优化生成器代码
    """生成器应用的场景是在大数据的范围中使用,切记不可直接用for遍历所有,可能无法短时间内获取所有数据"""
    def mygen():
        for i in range(1,101):
            yield i
    # 初始化生成器函数 => 生成器
    gen = mygen()
    print("<=====>")
    for i in range(30):
        num = next(gen)
        print("我的球衣号码是{}".format(num))
    print("<=====>")
    for i in range(40):
        num = next(gen)
        print("我的球衣号码是{}".format(num))
    
    # (3) send的使用方式 (给上一个yield发送数据)
    """
    # next和send区别:
    	next 只能取值
    	send 不但能取值,还能发送值
    # send注意点:
    	第一个 send 不能给 yield 传值 默认只能写None
    	最后一个yield 接受不到send的发送值
    """
    def mygen():
        print("start")
        res = yield "内部1"
        print(res,"<==内部==>")
        res = yield "内部2"
        print(res,"<==内部==>")
        res = yield "内部3"
        print(res,"<==内部==>")
        print("end")
    # 初始化生成器函数 => 生成器
    gen = mygen()
    # 第一次调用生成器
    """
    第一次调用生成器时,因为没有遇到yield保存的代码位置,
    无法发送数据,默认第一次只能发送None
    """
    res = gen.send(None)
    print(res,"<==外部==>")
    # 第二次调用生成器
    res = gen.send("100")
    print(res,"<==外部==>")
    # 第三次调用生成器
    res = gen.send("200")
    print(res,"<==外部==>")
    # 第四次调用生成器
    """
    error
    res = gen.send("300")
    print(res,"<==外部==>")
    """
    """
    使用send调用生成器,第一次发送时必须是None,因为还没有遇到yield保存的代码位置
    res = gen.send(None)  走到mygen生成器函数中
    print("start") 
    res = yield "内部1"  执行第80行 ,保存退出,记录当前代码位置,将 "内部1" 返回
    在98行接受数据  res = "内部1"  print(内部1,"<==外部==>")
    第二次调用生成器
    res = gen.send("100") 把100这个数据发送给上一次代码保存的位置80行进行接受. => 导致 80行 res = 100
    打印81行  print(100 ,"<==内部==>")
    执行83行  res = yield "内部2"  保存退出,记录当前代码位置,将 "内部2" 返回
    执行102行 res = gen.send("100") => "内部2" print("内部2","<==外部==>")
    ....
    依次类推 ... 
    到第四次调用时, 因为没有更多的yield 返回数据,gen.send(300)无法接受到返回值,所以出现停止迭代 StopIteration的报错,程序终止;
    """
    # (4) yield from 的使用
    """将一个可迭代对象变成一个迭代器返回	"""
    def mygen():
        lst = ["张磊","李亚峰","刘一峰","王同培"]
        yield from lst
    # 初始化生成器函数
    gen = mygen()
    print(next(gen))
    print(next(gen))
    print(next(gen))
    print(next(gen))
    # print(next(gen)) # StopIteration
    # (5) 斐波那契数列
    """使用生成器分段获取所有内容,而不是一股脑的把所有数据全部打印"""
    """1 1 2 3 5 8 13 21 34 .... """
    def mygen(maxval):
        a,b = 0,1
        i = 0
        while i < maxval:
            # print(b) 
            yield b
            a,b = b,a+b
            i += 1
    # mygen(10)
    gen = mygen(10)
    # 第一次获取
    for i in range(3):
        print(next(gen))
    # 第二次获取
    for i in range(5):
        print(next(gen))

    Python全栈推导式和生成器怎么实现

    Python全栈推导式和生成器怎么实现

    5. 小练习

    # 1.用推导式写如下程序
    # (1)构建如下列表:[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
    lst = [i * 2 for i in range(10)]
    lst = [i for i in range(0,19,2) ]
    print(lst)
    # (2)lst = ['alex', 'WuSir', '老男孩', '神秘男孩'] 将lst构建如下列表:['alex0', 'WuSir1', '老男孩2', '神秘男孩3']
    lst = ['alex', 'WuSir', '老男孩', '神秘男孩'] 
    # 方法一
    # lst = [i + str(lst.index(i)) for i in lst]
    # 方法二
    lst = [lst[i] + str(i) for i in range(len(lst)) ]
    print(lst)
    # (3)构建如下列表:[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
    lst = [ (j,i) for j in range(0,6) for i in range(1,7) if i-j == 1]
    print(lst)
    lst = [(i,i+1) for i in range(6)]
    print(lst)
    # (4)求出50以内能被3整除的数的平方,并放入到一个列表中。
    lst = [i ** 2 for i in range(51) if i % 3 == 0]
    print(lst)
    # (5)M = [[1,2,3],[4,5,6],[7,8,9]], 把M中3,6,9组成新列表
    M = [[1,2,3],[4,5,6],[7,8,9]]
    lst = [ i[-1] for i in M  ]
    print(lst)
    
    # (6)构建如下列表:['python1期', 'python2期', 'python3期', 'python4期', 'python6期', 'python7期', 'python8期', 'python9期', 'python10期']
    lst = [ "python{}期".format(i) for i in range(1,11) if i != 5 ]
    print(lst)
    # (7)过滤掉长度小于3的字符串列表 , 并转换成大写字母
    lst = ["sdfsdfsdfsdf","234","你说的符号是","a","ab"]
    lst = [ i.upper() for i in lst if len(i) >=3 ]
    print(lst)
    # (8)除了大小王,里面有52项,每一项是一个元组,请返回如下扑克牌列表[('红心','2'),('草花','J'), …('黑桃','A')] 
    lst1 = ["红心","草花","黑桃","方片"]
    lst2 = ["A","2","3","4","5","6","7","8","9","10","J","Q","K"]
    lst = [(i,j) for i in lst1 for j in lst2]
    print(lst)
    # 2.用推导式写如下程序
    lst1 = {
    		'name':'alex',
    		'Values':[
    			{'timestamp': 1517991992.94,'values':100,},			 
    			{'timestamp': 1517992000.94,'values': 200,},			
    			{'timestamp': 1517992014.94,'values': 300,},			 
    			{'timestamp': 1517992744.94,'values': 350},			 
    			{'timestamp': 1517992800.94,'values': 280}			 
    		]
    	}
    # 将lst1 转化成如下 lst2:
    lst2 = [
    	[1517991992.94, 100], 
    	[1517992000.94, 200], 
    	[1517992014.94, 300], 
    	[1517992744.94, 350], 
    	[1517992800.94, 280]
    ]
    # 方法一
    lst2 = [ [i["timestamp"] , i["values"]] for i in lst1["Values"] ]
    print(lst2)
    # 方法二
    lst2 = [ list(i.values()) for i in lst1["Values"]]
    print(lst2)
    
    # 3.读取一个文件所有内容,通过生成器调用一次获取一行数据.
    def mygen(filename):
    	with open(filename,mode="r+",encoding="utf-8") as fp:
    		for i in fp:
    			yield i 
    gen = mygen("ceshi111.txt")
    for i in range(3):
    	print(next(gen))
    for i in range(6):
    	print(next(gen))
    # 4.将普通求和函数改写成yield写法
    print("<====>")
    def add(a,b):
    	yield a + b
    mygen  = add(34,5)
    for i in mygen:
    	print(i)	

    到此,相信大家对“Python全栈推导式和生成器怎么实现”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI