iT邦幫忙

2022 iThome 鐵人賽

DAY 4
1
Software Development

闖進Python異世界系列 第 4

[Day 04] 闖進Python異世界 - List Comprehension

  • 分享至 

  • xImage
  •  

Python 的其中一個特色是「簡短」的程式碼,能有多短呢?來介紹一個形容詞叫做 'Pythonic',意思是很 Python。下面就來介紹這個形容詞吧!


Pythonic Code

大致分成兩類型介紹:

  1. 相對可讀性:以 swap 這個功能來說明

    • 非 Python 語言(e.g. C/C++)的寫法:
    a = 5
    b = 3
    temp = a
    a = b
    b = temp
    print(f"a = {a}, b = {b}")
    
    • Python 的寫法:
    a = 5
    b = 3
    a, b = b, a
    print(f"a = {a}, b = {b}")
    

    表面上看來,swap的邏輯確實是如 Python 的寫法,但是其他的程式語言大多都沒有設置這種寫法,這也就凸顯了 Python 在這個例子的可讀性。

  2. 簡潔有力:
    試試這個範例就知道了。如何將列表的元素設為1~100?

    • 非 Python 語言(e.g. C/C++)的寫法:
    list1 = []
    for i in range(1, 101):
        list1.append(i)
    print(list1)
    
    • Python 的寫法:
    list1 = [i for i in range(1, 101)]
    print(list1)
    

    這是什麼語法?答案就是我們今天的主題 List Comprehension


List Comprehension

這個是 Python 的黑魔法,把陣列與迴圈結合到極致。

介紹一下 List Comprehension 的語法吧!

前進語法

list = [修飾 源頭 篩選]

源頭

先從源頭說起,源頭出現的形式經常是一組 for item in iterable,其中 item 是「源頭」的主角,接下來的「篩選」、「修飾」都會與他有極大的關聯性!

item 是什麼?舉個例子:有一個迴圈長這樣 for i in range(0,50,2),這時候的 item 是 0, 2, ..., 46, 48

篩選

產生了一串源頭的 item 後,我們需要經過篩選的動作來決定哪些 item 是我需要的。

既然是「判斷」那我們就會使用 if else,與平常的不同的是這裡所寫的判斷式必須寫在一行之內(類似 C/C++ 的三元運算)。舉例來說,一個判斷是否為偶數的式子:True if n%2==0 else False 會以這種方式來表示。

遇到巢狀判斷怎麼解決?舉例來說,先判斷給定的數字是否為偶數,再判斷他是不是 3 的倍數。一行解會表示為 "multiple of 2" if n%2==0 else "multiple of 3" if n%3==0 else "none of above",雖然看起來很酷炫,但是當判斷開始增加,可讀性必定降低。

修飾

經過篩選後的 item 都是我們要的,現在要來決定他該以什麼形式出現在列表中,例如:平方、轉成字串、10倍等。

總結

List Comprehension 的運作順序為

  1. 「源頭」:for loop 的形式
  2. 「篩選」:單行 if else 形式,可以省略
  3. 「修飾」:取決於各人需求

小試身手

  1. 產生一個列表,內容物為 1~100 之間的偶數,即 2, 4, ..., 98, 100
list1 = [i for i in range(1, 101, 2)]
# or
list1 = [i for i in range(1, 101) if i%2==0]

說明一下第二種寫法:
源頭產生的數是1, 2, ..., 100, 101
篩選後留下 2 的倍數
不須修飾,因為 i 剛好就是我們要的結果

  1. 產生一個列表,內容物為 1, 4, 9, ..., 196, 225
list1 = [i**2 for i in range(1, 16)]

說明:
這些數字的規律是 1~15 各數的平方
所以源頭是產生 1~15
無需篩選,所以省略
修飾為各數平方

  1. 將下列程式碼以 List Comprehension 表示:
list1 = []
for i in range(20):
    if 2**i < 1000
        list1.append(2**i)
# List Comprehension
list1 = [2**i for i in range(20) if 2**i < 1000]
  1. 產生一個列表,內容物為 20 個 0
list1 = [0 for i in range(20)]

説明:
這題比較特別,源頭跟結果沒有太大的關係,產生的值直接設為 0


List Comprehension 把程式碼縮短到極致。
但是我們需要評估何時適合用 List Comprehension,因為有時候會造成可讀性大幅降低,有時候又可以縮短冗長的程式碼。

下一篇我們來介紹 Python 的 Quick Sort!


上一篇
[Day 03] 闖進Python異世界 - Methods of List
下一篇
[Day 05] 闖進Python異世界 - Quick Sort with List
系列文
闖進Python異世界30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
arguskao
iT邦新手 3 級 ‧ 2023-01-02 15:13:42

這篇太棒了,我從來都沒搞懂過!

我要留言

立即登入留言