推导式,集合推导式,生成器表达式及生成器函数day13
1.推导式
用一行循环判断遍历处一系列数据的方式
推导式在使用时,只能用for循环和判断,而且判断只能是单项判断
基本语法:
1 2 | lst = [i for i in range ( 1 , 51 )] print (lst) |
普通推导式
1 2 3 4 5 | #[1,2,3,4] => [2,8,24,64] lst = [ 1 , 2 , 3 , 4 ] #lst = [i*2**i for i in lst] lst = [i << i for i in lst] #左移 相当于 i*2**i print (lst) |
带有条件判断的推导式
1 2 3 4 5 6 7 8 9 10 | lst = [ 1 , 2 , 3 , 4 , 5 , 6 , 67 , 7 , 8 ,] lst_new = [] for i in lst: if i % 2 = = 0 : lst_new.append(i) print (lst_new) #推导式改写 lst = [i for i in lst if i % 2 = = 0 ] print (lst) |
多循环推导式
1 2 3 4 5 6 7 8 9 10 11 12 13 | lst1 = [ '王振' , '黄俊' , '刘伟' ] lst2 = [ '魏小林' , '刘思敏' , '陈芮' ] lst_new = [] for i in lst1: for j in lst2: res = i + '♥' + j lst_mwe.append(res) print (lst_new) #推导式改写 lst = [i + '♥' + j for i in lst1 for j in lst2] print (lst) |
带有判断条件的多循环推导式
1 2 3 4 5 6 7 8 9 10 11 12 | lst_new = [] for i in lst1: for j in lst2: if lst1.index(i) = = lst2.index(j): res = i + '♥' + j lst_new.append(res) print (lst_new) #推导式改写 lst = [i + '♥' + j for i in lst1 for j in lst2 if lst1.index(i) = = lst2.index(j)] print (lst) |
推导式练习:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | # ### 关于推导式的练习 # (1).{'x': 'A', 'y': 'B', 'z': 'C' } 把字典写成x=A,y=B,z=C的列表推导式 dic = { 'x' : 'A' , 'y' : 'B' , 'z' : 'C' } lst_new = [] #常规 for k,v in dic.items(): res = k + '=' + v lst_new.append(res) print (lst_new) lst = [k + '=' + v for k,v in dic.items()] #(2) 把列表中所有字符变成小写 ["ADDD","dddDD","DDaa","sss"] #常规 lst = [ "ADDD" , "dddDD" , "DDaa" , "sss" ] lst_new = [] for i in lst: res = i.lower() lst_new.append(res) print (lst_new) lst = [i.lower() for i in lst] print (lst) #(3)x是0-5之间的偶数,y是0-5之间的奇数 把x,y组成一起变成元组,放到列表当中 #方法一 lst_new = [] for x in range ( 6 ): for y in range ( 6 ): if x % 2 = = 0 and y % 2 = = 1 : res = x,y lst_new.append(res) print (lst_new) #推导式 lst = [(x,y) for x in range ( 6 ) for y in range ( 6 ) if x % 2 = = 0 and y % 2 = = 1 ] print (lst) #方法二 lst_new = [] for x in range ( 6 ): if x % 2 = = 0 : for y in range ( 6 ): if y % 2 = = 1 : res = x,y lst_new.append(res) print (lst_new) #(4) 使用列表推导式,制作所有99乘法表中的运算 for i in range ( 9 , 0 , - 1 ): 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 ( 9 , 0 , - 1 ) for j in range (i,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] = 18 M[2][0] * N[2][0] = 28 M[2][1] * N[2][1] = 32 M[2][2] * N[2][2] = 36 #总结:能控制下标等于控制了最后的结果 ''' #第一个效果 lst = [M[i][j] * N[i][j] for i in range ( 3 ) for j in range ( 3 )] print (lst) '''第一层循环控制外层i=0的时候,j=0,1,2''' #第二个效果 #[[],[],[]] 通过推导式遍历出三个新列表 lst = [[] for i in range ( 3 )] print (lst) ''' 外层i动的慢的,里层j动的快的,所有下标M[I][J] 在拿出i的时候,里面的for循环了三遍 是在一个新的列表当中实现的 ''' lst = [[M[i][j] * N[i][j] for j in range ( 3 )] for i in range ( 3 )] print (lst) |
2.集合推导式
案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ''' 案例: 满足年龄在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) #setvar = {三元运算符 + for i in iterable} setvar = { "尊贵VIP卡老" + i[ "name" ][ 0 ] if 18 < = i[ "age" ] < = 21 and 5000 < = i[ "money" ] < = 5500 else "抠脚大汉卡老" + i[ "name" ][ 0 ] for i in listvar} |
3.字典推导式
3.1 enumerate 函数
1 2 3 4 5 6 | enumerate (iterable,[start = 0 ]) 功能:枚举,将索引号和iterable中的值,一个一个拿出来配对组成元组放入迭代器中 参数: iterable:可迭代行数据(常用迭代器,容器数据类型,可迭代对象 range ) start:可选择开始的索引号(默认从 0 开始索引) 返回值:迭代器 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | lst = [ "吕洞宾" , "张果老" , "蓝采和" , "何仙姑" , "铁拐李" , "韩湘子" , "曹国舅" , "动感超人" ] it = enumerate (lst,start = 5 ) #可以设置开始是索引值 start = 5 from collections import Iterator,Iterable res = isinstance (it,Iterable) print (res) #for + next 迭代所有数据 for i in range ( 3 ): res = next (it) print (res) #list 强转迭代器 res = list (it) print (res) #1.通过推导式配合enumerate 实现 #(5,'吕洞宾') dic = {k:v for k,v in enumerate (lst,start = 1 )} print (dic) |
3.2 zip函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | zip (iterable,...,...) 功能:将多个iterable中的值,一个一个拿出来配对组成元组放入迭代器中 iterable:可迭代性数据(常用:迭代器,容器类数据类型,可迭代对象 range ) 返回值:迭代器 特点:不能配对的多余的值会被舍弃 zip 的基本使用 lst1 = [ "黄俊" , "朱佳怡" , "王振" , "魏小林" ] lst2 = [ "李博" , "刘伟" , "王颖倩" ] lst3 = [ "刘思敏" , "陈芮" ] it = zip (lst1,lst2) # it = zip(lst1,lst2,lst3) print ( isinstance (it,Iterator)) #用list强转,瞬间拿到里面所有数据 print ( list (it)) #[('黄俊', '李博'), ('朱佳怡', '刘伟'), ('王振', '王颖倩')] #1.使用zip配合推导式实现 dic = {k:v for k,v in zip (lst1,lst2)} print (dic) #通过dict 强转字典 实现 dic = dict ( zip (lst1,lst2)) #{'黄俊': '李博', '朱佳怡': '刘伟', '王振': '王颖倩'} print (dic) |
4.生成器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | 生成器本质是迭代器,允许自定义逻辑的迭代器 迭代器和生成器区别: 迭代器本身是系统内置的,重写不了,而生成器是用户自定义的,可以重写迭代逻辑 生成器可以用两个方式创建: ( 1 )生成器表达式(里面是推导式,外面用圆括号) ( 2 )生成器函数(用 def 定义,里面含有 yield ) from collections import Iterator #生成器表达式,定义一个生成器用元组括号就是生成器 gen = (i * 2 for i in range ( 1 , 5 )) print (gen) print ( isinstance (gen,Iterator)) #next调用生成器 res = next (gen) print (res) res = next (gen) print (res) res = next (gen) print (res) res = next (gen) print (res) #2.for调用生成器 gen = (i * 2 for i in range ( 1 , 5 )) for i in gen: print (i) #3.for + next 调用生成器 gen = (i * 2 for i in range ( 1 , 5 )) for i in range ( 2 ): res = next (gen) print (res) #4.用list强转,瞬间拿到所有数据 res = list (gen) print (res) |
5.生成器函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | yield 类似于 return 共同点在于:执行到这句话都会把值返回出去 不同点在于: yield 每次返回时,会记住上次离开时执行的位置,下次再调用生成器,会从上一次执行的位置继续往下走下去,而 return 直接终止函数,每次重头调用 yield 6 和 yield ( 6 ) 2 种写法都可以 yield 6 更推荐使用 from collections import Iterator ( 1 )基本语法 def mygen(): print ( 'one' ) yield 1 print ( 'two' ) yield 2 print ( 'three' ) yield 3 初始化生成器函数,返回生成器对象,简称生成器 gen = mygen() print ( isinstance (gen,Iterator)) #第一次 res = next (gen) print (res) #第二次 res = next (gen) #第三次 res = next (gen) print (res) 解析: 第一次调用, print ( 'one' ) yield 1 ,记录当前代码执行的状态在多少行,直接把 1 返回,等待一下次调用 res = 1 print ( 1 ) 第二次调用,从上一次代码的位置继续向下执行, print ( 'two' ) yield 2 ,记录当前代码执行的状态在多少行,直接把 2 返回回去,等待下一次调用 res = 2 print ( 2 ) 第三次调用,从上一次代码的位置继续向下执行, print ( 'three' ) yield 3 ,记录当前代码执行的状态在多少行,把 3 直接返回,等待下一次调用 res = 3 print ( 3 ) 如果在进行第四次调用,因为没有 yield 关键字返回数据,所以直接报错StopIteration |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | send 可以发送数据,发送给上一个 yield send 和 next 的区别 next 只能取值 send不但能取值,还能发送值 send注意点: 第一个send不能给 yield 传值,默认只能写 None 最后一个 yield 接收不到send的发送值 def mygen(): print ( 'start' ) res = yield 111 print (res) res = yield 222 print (res) res = yield 333 print (res) print ( 'end' ) #初始化生成器函数 -> 返回生成器对象 ->简称生成器 gen = mygen() #第一次调用 #第一次只能默认发送None,因为第一次没有上一个yield val = gen.send( None ) print (val) #第二次调用 val = gen.send( 444 ) print (val) #第三次调用 val = gen.send( 555 ) print (val) #555 #333 #第四次调用error #val = gen.send(666) #print(val) 解析: 无论是 next 还是send都可以调用生成器里面的数据,send不但可以调用,还可以给 yield 发送值 第一次调用send,只能发送 None ,因为还没有遇到 yield ,代码从上到下执行, print ( 'start' ) 遇到res = yield 111 记录当前代码执行的状态在多少行,把 111 值返回,等待一下调用外面的val = 111 print ( 111 ) 第二次代用send,把 444 发送给上一次保存的位置行, yield 进行接收res = 444 行往下执行, print ( 444 ) 遇到res = yield 222 记录当前代码执行的状态在多少行,把 222 值返回,等待下一次调用,外面的val = 222 print ( 222 ) 第三次调用send,把 555 发送给上一次保存的位置行, yield 进行接收res = 555 ,再往下执行, print ( 555 ),遇到res = yield 333 ,外面的val = 333 , print ( 333 ) 第四次调用send,把 666 发送给上一次保存的位置行, yield 进行接收res = 666 ,再往下执行, print ( 666 ), print ( 'end' ) 没有任何 yield 返回数据,出现StopIteration到此程序彻底结束、 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | yield from 将一个可迭代对象变成一个迭代器返回 def mygen(): lst = [ "魏小林" , "陈宁波" , "朱胜" ] yield from lst gen = mygen() print ( next (gen)) print ( next (gen)) print ( next (gen)) 案例:用生成器来写一个斐波那契数列 生成器应用在大数据的场景中,按照需求依次取值,切记不要直接迭代生成器所有数据 一旦数据量较大,类似于死循环 #0 1 1 2 3 5 8 13 21 34 55 ..... def mygen(maxlength): a = 0 b = 1 i = 0 while i <maxlength: yield b #当前值 = 上上个值 + 上一个值 a , b = b ,a + b i + = 1 gen = mygen( 50 ) for i in range ( 30 ): print ( next (gen)) |
__EOF__

本文作者:404 Not Found
本文链接:https://www.cnblogs.com/weiweivip666/p/12910271.html
关于博主:可能又在睡觉
版权声明:转载请注明出处
声援博主:如果看到我睡觉请喊我去学习
本文链接:https://www.cnblogs.com/weiweivip666/p/12910271.html
关于博主:可能又在睡觉
版权声明:转载请注明出处
声援博主:如果看到我睡觉请喊我去学习
-------------------------------------------
个性签名:代码过万,键盘敲烂!!!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人