Python 的其中一個特色是「簡短」的程式碼,能有多短呢?來介紹一個形容詞叫做 'Pythonic'
,意思是很 Python。下面就來介紹這個形容詞吧!
大致分成兩類型介紹:
相對可讀性:以 swap
這個功能來說明
a = 5
b = 3
temp = a
a = b
b = temp
print(f"a = {a}, b = {b}")
a = 5
b = 3
a, b = b, a
print(f"a = {a}, b = {b}")
表面上看來,swap
的邏輯確實是如 Python 的寫法,但是其他的程式語言大多都沒有設置這種寫法,這也就凸顯了 Python 在這個例子的可讀性。
簡潔有力:
試試這個範例就知道了。如何將列表的元素設為1~100?
list1 = []
for i in range(1, 101):
list1.append(i)
print(list1)
list1 = [i for i in range(1, 101)]
print(list1)
這是什麼語法?答案就是我們今天的主題 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 的運作順序為
for loop
的形式if else
形式,可以省略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
剛好就是我們要的結果
list1 = [i**2 for i in range(1, 16)]
說明:
這些數字的規律是 1~15 各數的平方
所以源頭是產生 1~15
無需篩選,所以省略
修飾為各數平方
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]
list1 = [0 for i in range(20)]
説明:
這題比較特別,源頭跟結果沒有太大的關係,產生的值直接設為 0
List Comprehension 把程式碼縮短到極致。
但是我們需要評估何時適合用 List Comprehension,因為有時候會造成可讀性大幅降低,有時候又可以縮短冗長的程式碼。
下一篇我們來介紹 Python 的 Quick Sort!