生成式 comprehension
生成式 ( 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)
微信扫码关注
抖音扫码关注