Python全棧之推導(dǎo)式和生成器
1. 推導(dǎo)式
# ### 推導(dǎo)式 : 通過(guò)一行循環(huán)判斷遍歷出一些列數(shù)據(jù)的方法叫做推導(dǎo)式 """ 語(yǔ)法: val for val in iterable """ # 1.推導(dǎo)式基本語(yǔ)法 lst = [] for i in range(1,51): lst.append(i) print(lst) # 改寫推導(dǎo)式 lst = [ i for i in range(1,51) ] print(lst) # 小練習(xí) # 1.[1,2,3,4,5] => [2,4,6,8,10] lst = [ i*2 for i in range(1,6) ] print(lst) # 2.帶有判斷條件的推導(dǎo)式 """注意點(diǎn):for后面緊跟的判斷條件只能是單項(xiàng)分支.""" """[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) # 改寫推導(dǎo)式 lst = [ i for i in lst if i % 2 == 1 ] print(lst) # 3.多循環(huán)推導(dǎo)式 # 誰(shuí)????誰(shuí) lst1 = ["孫杰龍","陳露","曹靜怡"] lst2 = ["王志國(guó)","鄧鵬","合理"] lst_new = [] for i in lst1: for j in lst2: lst_new.append(i+"????"+j) print(lst_new) # 改寫推導(dǎo)式 lst = [ i+"????"+j for i in lst1 for j in lst2 ] print(lst) # 4.帶有判斷條件的多循環(huán)推導(dǎo)式 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) # 改寫推導(dǎo)式 lst = [i+"????"+j for i in lst1 for j in lst2 if lst1.index(i) == lst2.index(j)] print(lst)
2. 推導(dǎo)式練習(xí)
# ### 推導(dǎo)式練習(xí)題 # (1).{'x': 'A', 'y': 'B', 'z': 'C' } 把字典寫成x=A,y=B,z=C的列表推導(dǎo)式 dic = {'x': 'A', 'y': 'B', 'z': 'C' } lst = [] for k,v in dic.items(): res = k + "=" + v lst.append(res) print(lst) # 推導(dǎo)式 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) # 推導(dǎo)式 lst = [ i.lower() for i in lst ] print(lst) # (3).x是0-5之間的偶數(shù),y是0-5之間的奇數(shù) 把x,y組成一起變成元組,放到列表當(dāng)中 # 方法一 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) # 推導(dǎo)式 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) # 推導(dǎo)式 lst = [ (x,y) for x in range(6) if x % 2 == 0 for y in range(6) if y % 2 == 1 ] print(lst) # (4).使用列表推導(dǎo)式 制作所有99乘法表中的運(yùn)算 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 """ # =>實(shí)現(xiàn)效果1 [2, 4, 6, 12, 15, 18, 28, 32, 36] """雙層循環(huán),外層循環(huán)動(dòng)的慢,內(nèi)層循環(huán)動(dòng)的快,正好符號(hào)M N 矩陣的下標(biāo)""" lst = [] for i in range(3): for j in range(3): lst.append( M[i][j] * N[i][j] ) print(lst) # =>實(shí)現(xiàn)效果2 [ [2, 4, 6], [12, 15, 18], [28, 32, 36] ] # 遍歷出三個(gè)空的列表 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. 集合_字典推導(dǎo)式
# ### 集合推導(dǎo)式 """ 案例: 滿足年齡在18到21,存款大于等于5000 小于等于5500的人, 開卡格式為:尊貴VIP卡老x(姓氏),否則開卡格式為:摳腳大漢卡老x(姓氏) 把開卡的種類統(tǒng)計(jì)出來(lái) """ lst = [ {"name":"趙沈陽(yáng)","age":18,"money":3000}, {"name":"趙萬(wàn)里","age":19,"money":5200}, {"name":"趙蜂擁","age":20,"money":100000}, {"name":"趙世超","age":21,"money":1000}, {"name":"王志國(guó)","age":18,"money":5500}, {"name":"王永飛","age":99,"money":5500} ] setvar = set() for i in lst: print(i) # {'name': '趙沈陽(yáng)', '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) # { 三元運(yùn)算符 + 推導(dǎo)式 } # 三運(yùn)運(yùn)算符 + 推導(dǎo)式 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) # ### 字典推導(dǎo)式 ### 一.enumerate """ enumerate(iterable,[start=0]) 功能:枚舉 ; 將索引號(hào)和iterable中的值,一個(gè)一個(gè)拿出來(lái)配對(duì)組成元組,通過(guò)迭代器返回 參數(shù): iterable: 可迭代性數(shù)據(jù) (常用:迭代器,容器類型數(shù)據(jù),可迭代對(duì)象range) start: 可以選擇開始的索引號(hào)(默認(rèn)從0開始索引) 返回值:迭代器 """ # 基本語(yǔ)法 from collections import Iterator,Iterable lst =["王文","呂洞賓","何仙姑","鐵拐李","張國(guó)老","曹國(guó)舅","藍(lán)采和","韓湘子"] it = enumerate(lst) it = enumerate(lst,start=100) print(isinstance(it,Iterator)) # next print( next(it) ) # for + next (推薦,數(shù)據(jù)較大時(shí)使用) for i in range(3): print(next(it)) # for for i in it: print(i) # list 強(qiáng)轉(zhuǎn)迭代器 print(list(it)) # (1) 字典推導(dǎo)式 配合 enumerate 來(lái)實(shí)現(xiàn) dic = {k:v for k,v in enumerate(lst,start=100)} print(dic) """ (100, '王文') (101, '呂洞賓') (102, '何仙姑') (103, '鐵拐李') (104, '張國(guó)老') (105, '曹國(guó)舅') (106, '藍(lán)采和') (107, '韓湘子') """ # (2) 使用dict強(qiáng)轉(zhuǎn)迭代器,瞬間得到字典 dic = dict( enumerate(lst,start=100) ) print(dic) ### 二.zip """ 特點(diǎn):按照索引配對(duì) zip(iterable, ... ...) 功能: 將多個(gè)iterable中的值,一個(gè)一個(gè)拿出來(lái)配對(duì)組成元組,通過(guò)迭代器返回 iterable: 可迭代性數(shù)據(jù) (常用:迭代器,容器類型數(shù)據(jù),可迭代對(duì)象range) 返回: 迭代器 """ # 基本語(yǔ)法 # lst1 = ["孫開啟","王永飛","于朝志"] # lst2 = ["薛宇健","韓瑞曉","上朝氣"] # lst3 = ["劉文博","歷史園","張光旭"] # 在索引下標(biāo)同時(shí)存在時(shí),才會(huì)進(jìn)行配對(duì),否則舍棄. lst1 = ["孫開啟","王永飛","于朝志"] lst2 = ["薛宇健","韓瑞曉"] lst3 = ["劉文博"] it = zip(lst1,lst2,lst3) print(list(it)) # (1) 字典推導(dǎo)式 配合 zip 來(lái)實(shí)現(xiàn) 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強(qiáng)轉(zhuǎn)迭代器,瞬間得到字典 dic = dict( zip(lst_key , lst_val) ) print(dic)
4. 生成器
4.1 生成器表達(dá)式
# ### 生成器 """ #生成器本質(zhì)是迭代器,允許自定義邏輯的迭代器 #迭代器和生成器區(qū)別: 迭代器本身是系統(tǒng)內(nèi)置的.重寫不了. 而生成器是用戶自定義的,可以重寫迭代邏輯 #生成器可以用兩種方式創(chuàng)建: (1)生成器表達(dá)式 (里面是推導(dǎo)式,外面用圓括號(hào)) (2)生成器函數(shù) (用def定義,里面含有yield) """ # (1) 生成器表達(dá)式 (里面是推導(dǎo)式,外面用圓括號(hào)) gen = ( i for i in range(10) ) print(gen) # 判斷類型 from collections import Iterator,Iterable print(isinstance(gen,Iterator)) # 1.next 調(diào)用生成器 print(next(gen)) print(next(gen)) # 2.for + next 調(diào)用生成器 for i in range(3): print(next(gen)) # 3.for 調(diào)用生成器所有數(shù)據(jù) for i in gen: print(i) # 4.list強(qiáng)轉(zhuǎn)生成器,瞬間得到所有數(shù)據(jù) gen = ( i for i in range(10) ) print(list(gen)) # print(next(gen)) error # StopIteration
4.2 生成器函數(shù)
# ### 生成器函數(shù) """ # yield 類似于 return 共同點(diǎn)在于:執(zhí)行到這句話都會(huì)把值返回出去 不同點(diǎn)在于:yield每次返回時(shí),會(huì)記住上次離開時(shí)執(zhí)行的位置 , 下次在調(diào)用生成器 , 會(huì)從上次執(zhí)行的位置往下走 而return直接終止函數(shù),每次重頭調(diào)用. yield 6 和 yield(6) 2種寫法都可以 yield 6 更像 return 6 的寫法 推薦使用 """ # (1) 基本語(yǔ)法 def mygen(): print("111") yield 1 print("222") yield 2 print("333") yield 3 # 初始化生成器函數(shù) => 返回生成器對(duì)象 => 簡(jiǎn)稱生成器 gen = mygen() # 第一次調(diào)用 res = next(gen) print(res) # 第二次調(diào)用 res = next(gen) print(res) # 第三次調(diào)用 res = next(gen) print(res) # 第四次調(diào)用 """ StopIteration error res = next(gen) print(res) """ """ # 第一次調(diào)用 print("111") yield 1 保存當(dāng)前第13行代碼的狀態(tài),把1返回,并且等待下一次調(diào)用 # 第二次調(diào)用 從上一次保存的位置13行往下走, print("222") yield 2 保存當(dāng)前第16行代碼的狀態(tài),把2返回,并且等待下一次調(diào)用 # 第三次調(diào)用 從上一次保存的位置16行往下走, print("333") yield 3 保存當(dāng)前第19行代碼的狀態(tài),把3返回,并且等待下一次調(diào)用 # 第四次調(diào)用 因?yàn)闆]有更多的yield 返回?cái)?shù)據(jù),所有停止迭代.出現(xiàn)報(bào)錯(cuò)異常. """ # (2) 優(yōu)化生成器代碼 """生成器應(yīng)用的場(chǎng)景是在大數(shù)據(jù)的范圍中使用,切記不可直接用for遍歷所有,可能無(wú)法短時(shí)間內(nèi)獲取所有數(shù)據(jù)""" def mygen(): for i in range(1,101): yield i # 初始化生成器函數(shù) => 生成器 gen = mygen() print("<=====>") for i in range(30): num = next(gen) print("我的球衣號(hào)碼是{}".format(num)) print("<=====>") for i in range(40): num = next(gen) print("我的球衣號(hào)碼是{}".format(num)) # (3) send的使用方式 (給上一個(gè)yield發(fā)送數(shù)據(jù)) """ # next和send區(qū)別: next 只能取值 send 不但能取值,還能發(fā)送值 # send注意點(diǎn): 第一個(gè) send 不能給 yield 傳值 默認(rèn)只能寫None 最后一個(gè)yield 接受不到send的發(fā)送值 """ def mygen(): print("start") res = yield "內(nèi)部1" print(res,"<==內(nèi)部==>") res = yield "內(nèi)部2" print(res,"<==內(nèi)部==>") res = yield "內(nèi)部3" print(res,"<==內(nèi)部==>") print("end") # 初始化生成器函數(shù) => 生成器 gen = mygen() # 第一次調(diào)用生成器 """ 第一次調(diào)用生成器時(shí),因?yàn)闆]有遇到y(tǒng)ield保存的代碼位置, 無(wú)法發(fā)送數(shù)據(jù),默認(rèn)第一次只能發(fā)送None """ res = gen.send(None) print(res,"<==外部==>") # 第二次調(diào)用生成器 res = gen.send("100") print(res,"<==外部==>") # 第三次調(diào)用生成器 res = gen.send("200") print(res,"<==外部==>") # 第四次調(diào)用生成器 """ error res = gen.send("300") print(res,"<==外部==>") """ """ 使用send調(diào)用生成器,第一次發(fā)送時(shí)必須是None,因?yàn)檫€沒有遇到y(tǒng)ield保存的代碼位置 res = gen.send(None) 走到mygen生成器函數(shù)中 print("start") res = yield "內(nèi)部1" 執(zhí)行第80行 ,保存退出,記錄當(dāng)前代碼位置,將 "內(nèi)部1" 返回 在98行接受數(shù)據(jù) res = "內(nèi)部1" print(內(nèi)部1,"<==外部==>") 第二次調(diào)用生成器 res = gen.send("100") 把100這個(gè)數(shù)據(jù)發(fā)送給上一次代碼保存的位置80行進(jìn)行接受. => 導(dǎo)致 80行 res = 100 打印81行 print(100 ,"<==內(nèi)部==>") 執(zhí)行83行 res = yield "內(nèi)部2" 保存退出,記錄當(dāng)前代碼位置,將 "內(nèi)部2" 返回 執(zhí)行102行 res = gen.send("100") => "內(nèi)部2" print("內(nèi)部2","<==外部==>") .... 依次類推 ... 到第四次調(diào)用時(shí), 因?yàn)闆]有更多的yield 返回?cái)?shù)據(jù),gen.send(300)無(wú)法接受到返回值,所以出現(xiàn)停止迭代 StopIteration的報(bào)錯(cuò),程序終止; """ # (4) yield from 的使用 """將一個(gè)可迭代對(duì)象變成一個(gè)迭代器返回 """ def mygen(): lst = ["張磊","李亞峰","劉一峰","王同培"] yield from lst # 初始化生成器函數(shù) gen = mygen() print(next(gen)) print(next(gen)) print(next(gen)) print(next(gen)) # print(next(gen)) # StopIteration # (5) 斐波那契數(shù)列 """使用生成器分段獲取所有內(nèi)容,而不是一股腦的把所有數(shù)據(jù)全部打印""" """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))
5. 小練習(xí)
# 1.用推導(dǎo)式寫如下程序 # (1)構(gòu)建如下列表:[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構(gòu)建如下列表:['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)構(gòu)建如下列表:[(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以內(nèi)能被3整除的數(shù)的平方,并放入到一個(gè)列表中。 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)構(gòu)建如下列表:['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)過(guò)濾掉長(zhǎng)度小于3的字符串列表 , 并轉(zhuǎn)換成大寫字母 lst = ["sdfsdfsdfsdf","234","你說(shuō)的符號(hào)是","a","ab"] lst = [ i.upper() for i in lst if len(i) >=3 ] print(lst) # (8)除了大小王,里面有52項(xiàng),每一項(xiàng)是一個(gè)元組,請(qǐng)返回如下?lián)淇伺屏斜韀('紅心','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.用推導(dǎo)式寫如下程序 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 轉(zhuǎn)化成如下 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.讀取一個(gè)文件所有內(nèi)容,通過(guò)生成器調(diào)用一次獲取一行數(shù)據(jù). 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.將普通求和函數(shù)改寫成yield寫法 print("<====>") def add(a,b): yield a + b mygen = add(34,5) for i in mygen: print(i)
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
springboot整合單機(jī)緩存ehcache的實(shí)現(xiàn)
本文主要介紹了springboot整合單機(jī)緩存ehcache的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02python print輸出延時(shí),讓其立刻輸出的方法
今天小編就為大家分享一篇python print輸出延時(shí),讓其立刻輸出的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-01-01python開發(fā)實(shí)時(shí)可視化儀表盤的示例
這篇文章主要介紹了python開發(fā)實(shí)時(shí)可視化儀表盤的示例,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下2021-05-05wxpython 最小化到托盤與歡迎圖片的實(shí)現(xiàn)方法
這篇文章主要分享一個(gè)python實(shí)例代碼,使用wxpython實(shí)現(xiàn)最小化到托盤與歡迎圖片,需要的朋友可以參考下2014-06-06Python安裝和配置uWSGI的詳細(xì)過(guò)程
這篇文章主要介紹了Python uWSGI 安裝配置,本文主要介紹如何部署簡(jiǎn)單的 WSGI 應(yīng)用和常見的 Web 框架,以 Ubuntu/Debian 為例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-07-07詳解基于Transformer實(shí)現(xiàn)電影評(píng)論星級(jí)分類任務(wù)
這篇文章主要為大家介紹了詳解基于Transformer實(shí)現(xiàn)電影評(píng)論星級(jí)分類任務(wù)過(guò)程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04python3第三方爬蟲庫(kù)BeautifulSoup4安裝教程
這篇文章主要為大家詳細(xì)介紹了python3第三方爬蟲庫(kù)BeautifulSoup4的安裝教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06Python?pandas?DataFrame基礎(chǔ)運(yùn)算及空值填充詳解
pandas除了可以drop含有空值的數(shù)據(jù)之外,當(dāng)然也可以用來(lái)填充空值,下面這篇文章主要給大家介紹了關(guān)于Python?pandas?DataFrame基礎(chǔ)運(yùn)算及空值填充的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07PyTorch 1.0 正式版已經(jīng)發(fā)布了
今天小編就為大家分享一篇關(guān)于PyTorch 1.0 正式版已經(jīng)發(fā)布了!小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12