生成式 ( 串列、字典、集合、元組 )
生成式 ( Comprehension ) 是 Python 的語法之一,可以運用在可迭代的物件上,只要撰寫一行程式碼就能完成多行的任務,大幅增加程式碼的簡潔性與可讀性,這篇教學將會介紹串列生成式、字典生成式和集合生成式 ( 元組 tuple 並沒有生成式,而是用類似生成式的方式產生 tuple )。
本篇使用的 Python 版本為 3.7.12,所有範例可使用 Google Colab 實作,不用安裝任何軟體 ( 參考:使用 Google Colab )
串列生成式
串列生成式只要撰寫一行程式碼,就能快速產生一個串列,其語法為:
result = [expression for item in iterable]
- result:生成的新串列。
- expression:生成的項目。
- item:從迭代物件裡取出的項目。
- iterable:可迭代的物件。
下方的程式碼裡,如果要產生一個 1~9 數字平方的串列,除了可以單純透過 for 迴圈搭配串列,也可以使用串列生成式來實現,串列生成式裡「[j*j for j in range(1,10)]
」,會依序取出 1~9 的數字,然後提供給最前方的 j,最後生成 jxj 的結果。
# 單純寫法
a = []
for i in range(1, 10):
a.append(i*i)
print(a) # [1, 4, 9, 16, 25, 36, 49, 64, 81]
# 使用串列生成式
b = [j*j for j in range(1,10)]
print(b) # [1, 4, 9, 16, 25, 36, 49, 64, 81]
再看一個例子:「有一個 a 串列,接著要建立一個 b 串列,b 串列每個內容項目是 a 串列的最大值減去其他項目的值」,這時使用串列生成式,整個程式碼就會變得非常簡潔。
# 單純寫法
a = [10,20,30,40,50,60,70,80,90]
b = []
for i in a:
b.append(max(a) - i) # 用 a 的最大值減去每個項目
print(b) # [80, 70, 60, 50, 40, 30, 20, 10, 0]
# 使用串列生成式
a = [10,20,30,40,50,60,70,80,90]
b = [max(a)-i for i in a]
print(b) # [80, 70, 60, 50, 40, 30, 20, 10, 0]
如果需要兩層 for 迴圈才能生成的串列,同樣也能使用串列生成式來產生。
# 單純寫法
# 將兩層 for 迴圈的 i 和 j 加在一起,變成新串列的項目
a = []
for i in 'abc':
for j in range(1,4):
a.append(i + str(j))
print(a) # ['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']
# 使用串列生成式
# 兩個 for 迴圈分別產生 i 和 j
a = [i + str(j) for i in 'abc' for j in range(1, 4)]
print(a) # ['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']
此外,串列生成式也可以加入 Python 的內建函式,針對產生的項目做處理,下面的程式,只要透過一行串列產生式,就能取出二維陣列裡的最小值。
# 單純寫法
a = [[100, 200, 300, 400, 500], [100, 200, 500, 2, 1]]
b = []
for i in a:
b.append(min(i)) # 將二維串列中每個串列裡的最小值取出,變成新的串列
print(min(b)) # 1,印出新的串列裡的最小值
# 使用串列生成式
a = [[100, 200, 300, 400, 500], [100, 200, 500, 2, 1]]
print(min([min(i) for i in a])) # 1
串列生成式搭配 if
串列生成式不僅能使用 for 迴圈快速產生串列,也可以搭配 if 判斷式,快速篩選並產生對應的內容,下方的程式碼,透過串列生成式,將 if 放在後方,就能直接產生一個偶數的串列。
# 單純寫法
a = []
for i in range(1,10):
if i%2 == 0:
a.append(i) # 取出偶數放入變數 a
print(a) # [2, 4, 6, 8]
# 使用串列生成式
a = [i for i in range(1, 10) if i%2 == 0]
print(a) # [2, 4, 6, 8]
如果將 if 放在 for 的前方,就必須加上 else ( 三元運算式 ( 條件運算式 ) ),下方的例子,會將偶數的項目保留,奇數項目替換成 100。
a = []
for i in range(1,10):
if i%2 == 0:
a.append(i) # 取出偶數放入變數 a
else:
a.append(100) # 如果是奇數,將 100 放入變數 a
print(a) # [100, 2, 100, 4, 100, 6, 100, 8, 100]
a = [i if i%2==0 else 100 for i in range(1, 10)]
print(a) # [100, 2, 100, 4, 100, 6, 100, 8, 100]
字典生成式
字典生成式只要撰寫一行程式碼,就能快速產生一個字典,其語法為:
result = {key: value for item in iterable}
- result:生成的新字典。
- key:生成的鍵。
- value:生成的值。
- item:從迭代物件裡取出的項目。
- iterable:可迭代的物件。
下方的例子,會建立一個項目數值平方的字典。
# 單純寫法
a = {}
for i in range(1,10):
a[i] = i*i # 將 i*i 對應指定的鍵
print(a) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
# 使用字典生成式
a = {i:i*i for i in range(1,10)}
print(a) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
集合生成式
集合生成式只要撰寫一行程式碼,就能快速產生一個集合,其語法為:
result = {value for item in iterable}
- result:生成的新集合。
- value:生成的值。
- item:從迭代物件裡取出的項目。
- iterable:可迭代的物件。
下方的例子,會建立一個項目數值平方的集合。
a = set()
for i in range(1,10):
a.add(i*i) # 將 i*i 新增到集合裡
print(a) # {64, 1, 4, 36, 9, 16, 49, 81, 25}
a = {i*i for i in range(1,10)}
print(a) # {64, 1, 4, 36, 9, 16, 49, 81, 25}
元組 ( 數組 ) 生成式
元組沒有生成式的語法,但是有類似的方式可以生成元組,其語法為:
variable = tuple(value for item in iterable)
- variable:型別為 tuple 的變數。
- value:生成的值。
- item:從迭代物件裡取出的項目。
- iterable:可迭代的物件。
a = tuple(i for i in range(10))
print(a) # (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
也可以使用運算式以及 if 判斷式產生 tuple。
a = tuple(i*i for i in range(10) if i>5)
print(a) # (36, 49, 64, 81)
意見回饋
如果有任何建議或問題,可傳送「意見表單」給我,謝謝~