推導(dǎo)式是 for 循環(huán)的簡化使用方法,使用推導(dǎo)式,將一個可迭代對象中的數(shù)據(jù)遍歷到某一個容器當中。簡單的來說就是用一行for循環(huán)語句,遍歷一個可迭代對象中的所有數(shù)據(jù),然后將遍歷出來的數(shù)據(jù)進行處理放入對應(yīng)的容器中的一個過程和方式。
創(chuàng)新互聯(lián)建站主要從事成都網(wǎng)站制作、成都做網(wǎng)站、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)大祥,十年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18980820575
和推導(dǎo)類似作用的還有三元運算符,三元運算符是條件判斷語句的簡化使用方法。
val for val in Iterable
就是 存入容器中的數(shù)據(jù)
+ for循環(huán)語句
推導(dǎo)式有三種表達方式,分別用對應(yīng)的符號包裹推導(dǎo)式語句。
列表推導(dǎo)試:[val for val in Iterable]
集合推導(dǎo)式:{val for val in Iterable}
字典推導(dǎo)式:{x,y for x,y in Iterable}
列表推到式,遍歷出來的數(shù)據(jù)最終就會變成一個列表數(shù)據(jù)。
列表中存入10條數(shù)據(jù)。
# 常規(guī)寫法
lst = []
for i in range(1, 11):
lst.append(i)
print(lst) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 推導(dǎo)式寫法
lst = [i for i in range(1, 11)]
print(lst) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
單循環(huán)推導(dǎo)式
# 處理容器中的數(shù)據(jù):[1, 2, 3, 4, 5] -> [3, 6, 9, 12, 15]
lst = [1, 2, 3, 4, 5]
# 普通寫法
new_lst = []
for i in lst:
res = i * 3
new_lst.append(res)
print(new_lst) # [3, 6, 9, 12, 15]
# 推導(dǎo)式寫法
new_lst = [i * 3 for i in lst]
print(new_lst) # [3, 6, 9, 12, 15]
帶有判斷條件的單循環(huán)推導(dǎo)式
# 過濾出奇數(shù)
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 普通寫法
new_lst = []
for i in lst:
if i % 2 == 1:
new_lst.append(i)
print(new_lst) # [1, 3, 5, 7, 9]
# 推導(dǎo)式寫法
# 推導(dǎo)式使用單項分支只能是在for語句結(jié)束之后使用
new_lst = [i for i in lst if i % 2 == 1]
print(new_lst) # [1, 3, 5, 7, 9]
多循環(huán)推導(dǎo)式
# 兩個列表中的數(shù)據(jù)相加求和
lst = [1, 2, 3]
lst1 = [11, 22, 33]
# 普通方法
new_lst = []
for i in lst:
for j in lst1:
res = i + j
new_lst.append(res)
print(new_lst) # [12, 23, 34, 13, 24, 35, 14, 25, 36]
# 推導(dǎo)式寫法
new_lst = [i + j for i in lst for j in lst1]
print(new_lst) # [12, 23, 34, 13, 24, 35, 14, 25, 36]
1、將字典中的數(shù)據(jù)變成['x=A', 'y=B', 'z=c']的樣式
{'x': 'A', 'y': 'B', 'z': 'C' }
2、將所用元素變成純小寫
["ADDD","dddDD","DDaa","sss"]
3、x是0-5之間的偶數(shù),y是0-5之間的奇數(shù) 把x,y組成一起變成元組,放到列表當中
4、使用列表推導(dǎo)式 制作所有99乘法表中的運算
5、求M,N中矩陣和元素的乘積
M = [[1,2,3], [4,5,6], [7,8,9]]
N = [[2,2,2], [3,3,3], [4,4,4]]
# 第五題解法之一
# =>實現(xiàn)效果1 [2, 4, 6, 12, 15, 18, 28, 32, 36]
# =>實現(xiàn)效果2 [[2, 4, 6], [12, 15, 18], [28, 32, 36]]
# 實現(xiàn)效果 1
lst_new = []
for i in range(len(M)) :
for j in range(len(N)) :
res = M[i][j] * N[i][j]
lst_new.append(res)
print(lst_new)
# 推導(dǎo)式寫法
res = [M[i][j]*N[i][j] for i in range(len(M)) for j in range(len(N))]
print(res)
# 實現(xiàn)效果 2
lst_new = []
for i in range(len(M)) :
lst_new2 = []
for j in range(len(N)) :
res = M[i][j] * N[i][j]
lst_new2.append(res)
lst_new.append(lst_new2)
print(lst_new)
# 推導(dǎo)式寫法
res = [[M[i][j]*N[i][j] for j in range(len(M))] for i in range(len(N))]
print(res)
集合推導(dǎo)式和列表推導(dǎo)式的用法基本一樣,但是外面使用大括號包括,得到的數(shù)據(jù)是一個集合。
'''
案例:
滿足年齡在18到21,存款大于等于5000,小于等于5500的人
開卡格式為:尊貴VIP卡老X(姓氏),否則開卡格式為:摳腳大漢老X(姓氏)
把開卡的種類統(tǒng)計出來
'''
lst = [
{"name": "劉鑫煒", "age": 18, "money": },
{"name": "劉聰", "age": 19, "money": 5100},
{"name": "劉子豪", "age": 20, "money": 4800},
{"name": "孔祥群", "age": 21, "money": 2000},
{"name": "宋云杰", "age": 18, "money": 20}
]
# 常規(guī)寫法
setvar = set()
for i in lst:
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) # {'尊貴VIP老劉', '摳腳老漢劉', '摳腳老漢孔', '摳腳老漢宋'}
# 打印顯示只有4個元素,是因為集合的自動去重
# 使用集合推導(dǎo)式
# 推導(dǎo)式只能使用單項分支,但是可以在返回值使用三元運算符
setvar = {
"尊貴VIP卡老" + i["name"][0] if 18 <= i["age"] <= 21 and 5000 <= i["money"] <= 5500 else "摳腳大漢卡老" + i["name"][0] for i in lst}
print(setvar) # {'摳腳大漢卡老孔', '摳腳大漢卡老劉', '尊貴VIP卡老劉', '摳腳大漢卡老宋'}
字典推導(dǎo)式也是一樣的用法,但是字典的數(shù)據(jù)是以鍵值對的形式存在的,所以返回的數(shù)據(jù)、或者要將返回的數(shù)據(jù)變成兩個,以對應(yīng)鍵值。
將列表中的鍵值對的變成一個字典
lst = [{'A': 'a'}, {'B': 'b'}]
dct = {k:v for i in lst for k,v in i.items()}
print(dct) # {'A': 'a', 'B': 'b'}
函數(shù) | 作用 |
---|---|
enumerate | 枚舉,根據(jù)索引號碼將可迭代對象中的值一一配對成元組,返回迭代器。 |
zip | 將多個可迭代對象中的值一一對應(yīng)組成元組,返回迭代器。 |
枚舉,根據(jù)索引號碼 和 Iterable 中的值,一個一個拿出來配對組成元組,放入迭代器中,然后返回迭代器。
enumerate(iterable, [start = 0])
iterable:可迭代數(shù)據(jù)
start:可以選擇開始的索引號(默認從0開始索引)
迭代器
from collections import Iterator
lst = ['東', '南', '西', '北']
# 基本使用
it = enumerate(lst) # 實現(xiàn)功能返回迭代器
print(isinstance(it, Iterator)) # True
# 強轉(zhuǎn)成列表
new_lst = list(it)
print(new_lst) # [(0, '東'), (1, '南'), (2, '西'), (3, '北')]
"""
可以看到里面的元列表中的數(shù)據(jù)和對應(yīng)的索引號碼一一對應(yīng)成了元組
"""
上面的舉例當中,如果使用字典推導(dǎo)式和enumerate函數(shù)配合,就可以用一句話達成組成一個字典的目的。
from collections import Iterator
lst = ['東', '南', '西', '北']
# enumerate 配合使用字典推導(dǎo)式 變成字典
dct = {k: v for k, v in enumerate(lst)}
print(dct) # {0: '東', 1: '南', 2: '西', 3: '北'}
將多個Iterable中的值,一個一個拿出來配對組成元組放入迭代器中,如果某個元素多出,沒有匹配項就會被舍棄。
zip(iterable, iterable1, ……)
參數(shù)就是一個個的可迭代對象。
迭代器
下面的舉例當中,將三個列表中的元素以一一對應(yīng)組成元組,但是最小的列表中只有三個元素,所以只能一一對應(yīng)組成三對元組,而多出的元素就被舍棄。
lst1 = [1, 2, 3, 4, 5]
lst2 = ['a', 'b', 'c', 'd']
lst3 = ['A', 'B', 'C']
it = zip(lst1, lst2, lst3)
lst = list(it)
print(lst) # [(1, 'a', 'A'), (2, 'b', 'B'), (3, 'c', 'C')]
推導(dǎo)式我們到此學(xué)習完了,但是我們就發(fā)現(xiàn),推導(dǎo)式就是在容器中使用一個for循環(huán)而已,為什么沒有元組推導(dǎo)式?
請見生成器
在有的時候,我們需要在一個列表或者其它的一些容器中存放大量的值,我們一般會怎么使用呢?比如在初始化一個列表的時候我們使用for循環(huán)和append的方法去創(chuàng)建嗎?
這里大家注意,如果條件允許的話,那么我們一定是要優(yōu)先使用推導(dǎo)式而不是for循環(huán)加append的方式,原因很簡單,因為底層邏輯的不同,使推導(dǎo)式的執(zhí)行速度相比for循環(huán)加append更快。
import time
# 列表循環(huán)插入數(shù)據(jù)
start_time = time.perf_counter()
lst = []
for i in range():
lst.append(i)
end_time = time.perf_counter()
print(end_time - start_time) # 1.
""" 推導(dǎo)式比循環(huán)速度更快 """
start_time = time.perf_counter()
new_lst1 = [i for i in range()]
end_time = time.perf_counter()
print(end_time - start_time) # 0.
經(jīng)過測試我們可以看到,推導(dǎo)式的速度大約是for循環(huán)的2倍多,是什么導(dǎo)致的?還記得我們之前使用過的dis
模塊嗎?
import dis
def loop():
lst = []
for i in range(10):
lst.append(i)
return lst
def der():
lst = [i for i in range(10)]
return lst
dis.dis(loop)
print('-' * 100)
dis.dis(der)
結(jié)果如下:
4 0 BUILD_LIST 0
2 STORE_FAST 0 (lst)
5 4 SETUP_LOOP 26 (to 32)
6 LOAD_GLOBAL 0 (range)
8 LOAD_CONST 1 (10)
10 CALL_FUNCTION 1
12 GET_ITER
>> 14 FOR_ITER 14 (to 30)
16 STORE_FAST 1 (i)
6 18 LOAD_FAST 0 (lst)
20 LOAD_ATTR 1 (append)
22 LOAD_FAST 1 (i)
24 CALL_FUNCTION 1
26 POP_TOP
28 JUMP_ABSOLUTE 14
>> 30 POP_BLOCK
7 >> 32 LOAD_FAST 0 (lst)
34 RETURN_VALUE
-----------------------------------------------------------------------------
11 0 LOAD_CONST 1 (<code object <listcomp> at 0x000002C71AD950C0, file "tset.py", line 11>)
2 LOAD_CONST 2 ('der.<locals>.<listcomp>')
4 MAKE_FUNCTION 0
6 LOAD_GLOBAL 0 (range)
8 LOAD_CONST 3 (10)
10 CALL_FUNCTION 1
12 GET_ITER
14 CALL_FUNCTION 1
16 STORE_FAST 0 (lst)
12 18 LOAD_FAST 0 (lst)
20 RETURN_VALUE
從上述結(jié)果中我們就是可以看出,在這種情況下,for循環(huán)因為開始定義列表、循環(huán)中的append方法的是使用,比推導(dǎo)式要多出幾個環(huán)節(jié),因此速度相比之下變得很慢,這就是原因。
再次我們也再說一句,之后碰到關(guān)于速度和底層之類的疑惑的時候,就可以簡單的使用timeit
和dis
去驗證和簡答的理解。
分享題目:Python推導(dǎo)式
當前URL:http://chinadenli.net/article18/dsogpdp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司、微信公眾號、品牌網(wǎng)站建設(shè)、標簽優(yōu)化、ChatGPT、用戶體驗
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)