溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

Python推導(dǎo)式如何使用

發(fā)布時(shí)間:2022-05-13 13:55:40 來(lái)源:億速云 閱讀:151 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本文小編為大家詳細(xì)介紹“Python推導(dǎo)式如何使用”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Python推導(dǎo)式如何使用”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來(lái)學(xué)習(xí)新知識(shí)吧。

    推導(dǎo)式

    什么是推導(dǎo)式

    推導(dǎo)式是 for 循環(huán)的簡(jiǎn)化使用方法,使用推導(dǎo)式,將一個(gè)可迭代對(duì)象中的數(shù)據(jù)遍歷到某一個(gè)容器當(dāng)中。簡(jiǎn)單的來(lái)說(shuō)就是用一行for循環(huán)語(yǔ)句,遍歷一個(gè)可迭代對(duì)象中的所有數(shù)據(jù),然后將遍歷出來(lái)的數(shù)據(jù)進(jìn)行處理放入對(duì)應(yīng)的容器中的一個(gè)過(guò)程和方式。

    和推導(dǎo)類(lèi)似作用的還有三元運(yùn)算符,三元運(yùn)算符是條件判斷語(yǔ)句的簡(jiǎn)化使用方法。

    語(yǔ)法:

    val for val in Iterable

    就是存入容器中的數(shù)據(jù)for循環(huán)語(yǔ)句

    推導(dǎo)式有三種表達(dá)方式,分別用對(duì)應(yīng)的符號(hào)包裹推導(dǎo)式語(yǔ)句:

    • 列表推導(dǎo)試:[val for val in Iterable]

    • 集合推導(dǎo)式:{val for val in Iterable}

    • 字典推導(dǎo)式:{x,y for x,y in Iterable}

    列表推導(dǎo)式:

    列表推到式,遍歷出來(lái)的數(shù)據(jù)最終就會(huì)變成一個(gè)列表數(shù)據(jù)。

    基本語(yǔ)法

    列表中存入10條數(shù)據(jù):

    # 常規(guī)寫(xiě)法
    lst = []
    for i in range(1, 11):
        lst.append(i)
    print(lst)  # [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    
    # 推導(dǎo)式寫(xiě)法
    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]
    # 普通寫(xiě)法
    new_lst = []
    for i in lst:
    	res = i * 3
    	new_lst.append(res)
    print(new_lst)  # [3, 6, 9, 12, 15]
    
    # 推導(dǎo)式寫(xiě)法
    new_lst = [i * 3 for i in lst]
    print(new_lst)  # [3, 6, 9, 12, 15]

    帶有判斷條件的單循環(huán)推導(dǎo)式:

    # 過(guò)濾出奇數(shù)
    lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    # 普通寫(xiě)法
    new_lst = []
    for i in lst:
    	if i % 2 == 1:
    		new_lst.append(i)
    print(new_lst)  # [1, 3, 5, 7, 9]
    
    # 推導(dǎo)式寫(xiě)法
    # 推導(dǎo)式使用單項(xiàng)分支只能是在for語(yǔ)句結(jié)束之后使用
    new_lst = [i for i in lst if i % 2 == 1]
    print(new_lst)  # [1, 3, 5, 7, 9]

    多循環(huán)推導(dǎo)式:

    # 兩個(gè)列表中的數(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)式寫(xiě)法
    new_lst = [i + j for i in lst for j in lst1]
    print(new_lst)  # [12, 23, 34, 13, 24, 35, 14, 25, 36]

    列表推導(dǎo)式練習(xí)題

    • 1、將字典中的數(shù)據(jù)變成['x=A', 'y=B', 'z=c']的樣式

    {'x': 'A', 'y': 'B', 'z': 'C' }

    • 2、將所用元素變成純小寫(xiě)

    ["ADDD","dddDD","DDaa","sss"]

    • 3、x是0-5之間的偶數(shù),y是0-5之間的奇數(shù) 把x,y組成一起變成元組,放到列表當(dāng)中

    • 4、使用列表推導(dǎo)式 制作所有99乘法表中的運(yùn)算

    • 5、求M,N中矩陣和元素的乘積

    M = [[1,2,3], [4,5,6], [7,8,9]]
    N = [[2,2,2], [3,3,3], [4,4,4]]

    # 第五題解法之一
    
    # =>實(shí)現(xiàn)效果1   [2, 4, 6, 12, 15, 18, 28, 32, 36]
    # =>實(shí)現(xiàn)效果2   [[2, 4, 6], [12, 15, 18], [28, 32, 36]]
    # 實(shí)現(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)式寫(xiě)法
    res = [M[i][j]*N[i][j] for i in range(len(M)) for j in range(len(N))]
    print(res)
    # 實(shí)現(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)式寫(xiě)法
    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)式和列表推導(dǎo)式的用法基本一樣,但是外面使用大括號(hào)包括,得到的數(shù)據(jù)是一個(gè)集合。

    例題:

    '''
    案例:
    	滿(mǎn)足年齡在18到21,存款大于等于5000,小于等于5500的人
    	開(kāi)卡格式為:尊貴VIP卡老X(姓氏),否則開(kāi)卡格式為:摳腳大漢老X(姓氏)
    	把開(kāi)卡的種類(lèi)統(tǒng)計(jì)出來(lái)
    '''
    lst = [
    	{"name": "劉鑫煒", "age": 18, "money": 10000},
    	{"name": "劉聰", "age": 19, "money": 5100},
    	{"name": "劉子豪", "age": 20, "money": 4800},
    	{"name": "孔祥群", "age": 21, "money": 2000},
    	{"name": "宋云杰", "age": 18, "money": 20}
    ]
    
    # 常規(guī)寫(xiě)法
    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個(gè)元素,是因?yàn)榧系淖詣?dòng)去重
    
    # 使用集合推導(dǎo)式
    # 推導(dǎo)式只能使用單項(xiàng)分支,但是可以在返回值使用三元運(yùn)算符
    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)式

    字典推導(dǎo)式也是一樣的用法,但是字典的數(shù)據(jù)是以鍵值對(duì)的形式存在的,所以返回的數(shù)據(jù)、或者要將返回的數(shù)據(jù)變成兩個(gè),以對(duì)應(yīng)鍵值。

    基礎(chǔ)語(yǔ)法:

    將列表中的鍵值對(duì)的變成一個(gè)字典

    lst = [{'A': 'a'}, {'B': 'b'}]
    
    dct = {k:v for i in lst for k,v in i.items()}
    
    print(dct)  # {'A': 'a', 'B': 'b'}

    字典推導(dǎo)式常用以配合的函數(shù)

    函數(shù)作用
    enumerate枚舉,根據(jù)索引號(hào)碼將可迭代對(duì)象中的值一一配對(duì)成元組,返回迭代器。
    zip將多個(gè)可迭代對(duì)象中的值一一對(duì)應(yīng)組成元組,返回迭代器。

    enumerate

    功能:

    枚舉,根據(jù)索引號(hào)碼 和 Iterable 中的值,一個(gè)一個(gè)拿出來(lái)配對(duì)組成元組,放入迭代器中,然后返回迭代器。

    語(yǔ)法:

    enumerate(iterable, [start = 0])

    參數(shù):

    iterable:可迭代數(shù)據(jù)
    start:可以選擇開(kāi)始的索引號(hào)(默認(rèn)從0開(kāi)始索引)

    基本語(yǔ)法:

    from collections import Iterator
    lst = ['東', '南', '西', '北']
    # 基本使用
    it = enumerate(lst)  # 實(shí)現(xiàn)功能返回迭代器
    print(isinstance(it, Iterator))	 # True
    # 強(qiáng)轉(zhuǎn)成列表
    new_lst = list(it)
    print(new_lst)  # [(0, '東'), (1, '南'), (2, '西'), (3, '北')]
    """
    可以看到里面的元列表中的數(shù)據(jù)和對(duì)應(yīng)的索引號(hào)碼一一對(duì)應(yīng)成了元組
    """

    上面的舉例當(dāng)中,如果使用字典推導(dǎo)式和enumerate函數(shù)配合,就可以用一句話達(dá)成組成一個(gè)字典的目的。

    from collections import Iterator
    lst = ['東', '南', '西', '北']
    # enumerate 配合使用字典推導(dǎo)式 變成字典
    dct = {k: v for k, v in enumerate(lst)}
    print(dct)  # {0: '東', 1: '南', 2: '西', 3: '北'}

    zip

    功能:

    將多個(gè)Iterable中的值,一個(gè)一個(gè)拿出來(lái)配對(duì)組成元組放入迭代器中,如果某個(gè)元素多出,沒(méi)有匹配項(xiàng)就會(huì)被舍棄。

    語(yǔ)法:

    zip(iterable, iterable1, &hellip;&hellip;)

    參數(shù)就是一個(gè)個(gè)的可迭代對(duì)象。

    基本語(yǔ)法:

    下面的舉例當(dāng)中,將三個(gè)列表中的元素以一一對(duì)應(yīng)組成元組,但是最小的列表中只有三個(gè)元素,所以只能一一對(duì)應(yīng)組成三對(duì)元組,而多出的元素就被舍棄。

    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')]

    為什么沒(méi)有元組推導(dǎo)式?

    推導(dǎo)式我們到此學(xué)習(xí)完了,但是我們就發(fā)現(xiàn),推導(dǎo)式就是在容器中使用一個(gè)for循環(huán)而已,為什么沒(méi)有元組推導(dǎo)式?

    優(yōu)先使用推導(dǎo)式

    在有的時(shí)候,我們需要在一個(gè)列表或者其它的一些容器中存放大量的值,我們一般會(huì)怎么使用呢?比如在初始化一個(gè)列表的時(shí)候我們使用for循環(huán)和append的方法去創(chuàng)建嗎?

    這里大家注意,如果條件允許的話,那么我們一定是要優(yōu)先使用推導(dǎo)式而不是for循環(huán)加append的方式,原因很簡(jiǎn)單,因?yàn)榈讓舆壿嫷牟煌?,使推?dǎo)式的執(zhí)行速度相比f(wàn)or循環(huán)加append更快。

    import time
    # 列表循環(huán)插入數(shù)據(jù)
    start_time = time.perf_counter()
    lst = []
    for i in range(15000000):
        lst.append(i)
    end_time = time.perf_counter()
    print(end_time - start_time)  # 1.7453036000000002
    
    """ 推導(dǎo)式比循環(huán)速度更快 """
    start_time = time.perf_counter()
    new_lst1 = [i for i in range(15000000)]
    end_time = time.perf_counter()
    print(end_time - start_time)  # 0.7337192000000001

    經(jīng)過(guò)測(cè)試我們可以看到,推導(dǎo)式的速度大約是for循環(huán)的2倍多,是什么導(dǎo)致的?還記得我們之前使用過(guò)的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)因?yàn)殚_(kāi)始定義列表、循環(huán)中的append方法的是使用,比推導(dǎo)式要多出幾個(gè)環(huán)節(jié),因此速度相比之下變得很慢,這就是原因。

    再次我們也再說(shuō)一句,之后碰到關(guān)于速度和底層之類(lèi)的疑惑的時(shí)候,就可以簡(jiǎn)單的使用timeitdis去驗(yàn)證和簡(jiǎn)答的理解。

    讀到這里,這篇“Python推導(dǎo)式如何使用”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識(shí)點(diǎn)還需要大家自己動(dòng)手實(shí)踐使用過(guò)才能領(lǐng)會(huì),如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

    向AI問(wèn)一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI