Python 的列表推導(dǎo)
如果需要生成一個長度為 3、內(nèi)容為 0 的列表,可以使用如下的代碼來完成這項任務(wù):
list = [0, 0, 0]
如果需要生成一個長度為 100、內(nèi)容為 0 的列表,使用如上的方式完成,需要在括號中書寫 100 個 0,既繁瑣又容易出錯,顯然是不合適的??梢允褂脛討B(tài)的方式完成這項任務(wù):
list = []
for i in range(100):
list.append(0)
- 在第 1 行,創(chuàng)建一個空的列表
- 在第 2 行,創(chuàng)建一個循環(huán)語句,循環(huán) 100 次
- 在第 3 行,在循環(huán)中,向列表添加元素 0
- 最終,list 包含 100 個整數(shù) 0
如果需要生成一個包含 0 到 100 之間(不包括 100)所有的偶數(shù)的列表,可以在以上的代碼基礎(chǔ)上進(jìn)行修改,如下所示:
list = []
for i in range(100):
if i % 2 == 0:
list.append(i)
- 在第 1 行,創(chuàng)建一個空的列表
- 在第 2 行,創(chuàng)建一個循環(huán)語句,循環(huán) 100 次
- 在第 3 行,檢查循環(huán)變量 i 能否被 2 整除
- 在第 4 行,如果變量 i 能夠被 2 整除,則表示變量 i 是偶數(shù),將其加入到列表中
- 最終,list 包含 0 到 100 之間的所有的偶數(shù)
在 Python 編程中會碰到大量的創(chuàng)建列表的場景,使用如上的動態(tài)添加的方式可以完成這樣的需求,但是代碼不夠簡潔。Python 提供了列表推導(dǎo)的語法用于快速的構(gòu)建一個列表,完成類似如下的任務(wù):
- 生成一個包含 100 個整數(shù) 0 的列表
- 生成一個包含 0 到 100 之間的所有偶數(shù)的列表
類似的,Python 提供了集合推導(dǎo)的語法用于快速的構(gòu)建一個集合,以及字典推導(dǎo)的語法用于快速的構(gòu)建一個字典。
1. 列表推導(dǎo)
1.1 定義
1.1.1 定義
列表推導(dǎo)式對應(yīng)的英文是 list comprehension,有時也被翻譯為列表解析式,是一種創(chuàng)建列表的簡潔語法。它的基本語法定義如下:
[expression for item iteratable]
可以認(rèn)為它使用如下代碼創(chuàng)建了一個 list:
list = []
for item iteratable:
list.append(expression)
- 在第 1 行,創(chuàng)建一個空的列表
- 在第 2 行,創(chuàng)建一個循環(huán)語句,遍歷 iteratable
- 在第 3 行,在循環(huán)中,向列表添加元素 expression
1.1.2 例子 1
使用列表推導(dǎo)生成一個包含 4 個整數(shù) 0 的列表,代碼如下:
>>> [0 for i in range(4)]
[0, 0, 0, 0]
等價于使用 append 方法創(chuàng)建列表,代碼如下:
>>> list = []
>>> for i in range(4):
... list.append(0)
...
>>> list
[0, 0, 0, 0]
1.1.3 例子 2
使用列表推導(dǎo)生成一個包含 0 到 4 之間所有整數(shù)的列表,代碼如下:
>>> [i for i in range(4)]
[0, 1, 2, 3]
等價于使用 append 方法創(chuàng)建列表,代碼如下:
>>> list = []
>>> for i in range(4):
... list.append(i)
...
>>> list
[0, 0, 0, 0]
1.2 條件語句
在基本的列表推導(dǎo)中,將 for 循環(huán)遍歷的全部元素加入到列表中,可以在 for 循環(huán)之后添加 if 語句用于選擇元素,它的語法定義如下:
[expression for item iteratable if condition]
可以認(rèn)為它使用如下代碼創(chuàng)建了一個 list:
list = []
for item iteratable:
if condition:
list.append(expression)
注意,在第 3 行,只有滿足條件,才會將元素添加到列表中。
使用列表推導(dǎo)生成一個包含 0 到 4 之間所有偶數(shù)的列表,使用 if i % 2 == 0 選擇將偶數(shù)加入到列表,代碼如下:
>>> [i for i in range(4) if i % 2 == 0]
[0, 2]
等價于使用 append 方法創(chuàng)建列表,代碼如下:
>>> list = []
>>> for i in range(4):
... if i % 2 == 0:
... list.append(i)
...
>>> list
[0, 2]
1.3 for 循環(huán)嵌套
列表推導(dǎo)中允許 for 循環(huán)嵌套,它的語法定義如下:
[expression for x in X for y in Y]
可以認(rèn)為它使用如下代碼創(chuàng)建了一個 list:
list = []
for x in X:
for y in Y:
list.append(expression)
使用列表推導(dǎo)生成一個包含兩個字符的字符串列表,代碼如下:
>>> [x + y for x in 'ABC' for y in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
等價于使用 append 方法創(chuàng)建列表,代碼如下:
>>> list = []
>>> for x in 'ABC':
... for y in 'XYZ':
... list.append(x + y)
...
>>> list
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
- 在第 1 行,創(chuàng)建了一個空列表
- 在第 2 行,在外循環(huán)中,遍歷字符串 ‘ABC’ 中的 3 個字符 ‘A’、‘B’ 和 ‘C’,循環(huán)變量 x 依次為’A’、‘B’ 和 ‘C’
- 在第 3 行,在內(nèi)循環(huán)中,遍歷字符串 ‘XYZ’ 中的 3 個字符 ‘X’、‘Y’ 和 ‘Z’,循環(huán)變量 y 依次為’X’、‘Y’ 和 ‘Z’
- 在第 4 行,將表達(dá)式 x + y 作為元素添加到列表中
1.4 應(yīng)用舉例
- 初始化長度為 10 的列表
>>> [0 for i in range(10)]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
- 將列表中的元素乘以 10
>>> list = [1, 2, 3]
>>> [i*10 for i in list]
[10, 20, 30]
- 將列表中所有的字符串變成大寫
>>> list = ['www', 'imooc', 'com']
>>> [i.upper() for i in list]
['WWW', 'IMOOC', 'COM']
- 包含所有的正整數(shù)的列表
>>> list = [-1, 1, -2, 2, -3, 3]
>>> [i for i in list if i > 0]
[1, 2, 3]
- 初始化生成一個 M*N 的矩陣
>>> M = 2
>>> N = 3
>>> matrix = [[0 for col in range(N)] for row in range(M)]
>>> matrix
[[0,0,0], [0,0,0]]
- 在第 1 行,設(shè)定矩陣的行數(shù) M 為 2
- 在第 2 行,設(shè)定矩陣的列數(shù) N 為 3
- 在第 3 行,生成一個 2 行 3 列的矩陣
- [0 for col in range (N)],生成包含 3 個元素的一維向量
- [[…] for row in range (M)],生成包含 2 個一維向量的矩陣
- 將矩陣平坦化
>>> matrix = [[1,2,3],[4,5,6]]
>>> matrix2 = [matrix[row][col] for row in range(2) for col in range(3)]
>>> matrix2
[1,2,3,4,5,6]
- 在第 1 行,生成一個 2 行 3 列的矩陣
- 矩陣的第 1 行為 [1,2,3]
- 矩陣的第 2 行為 [4,5,6]
- 在第 2 行,將矩陣平坦化
- for row in range (2) 遍歷矩陣的行
- for col in range (3) 遍歷矩陣的列
- matrix [row][col] 獲取矩陣中指定位置的元素,將該元素放置在一個列表中
- 在的 3 行,得到一個平坦化的列表
2. 集合推導(dǎo)
2.1 定義
列表推導(dǎo)用于快速生成一個列表,類似的,Python 同時提供了集合推導(dǎo)用于快速生成一個集合,語法如下:
{expression for item iteratable}
可以認(rèn)為它使用如下代碼創(chuàng)建了一個集合:
s = set()
for item iteratable:
s.add(expression)
- 在第 1 行,使用函數(shù) set () 創(chuàng)建一個空的集合
- 在第 2 行,創(chuàng)建一個循環(huán)語句,遍歷 iteratable
- 在第 3 行,在循環(huán)中,向集合添加元素 expression
與列表推導(dǎo)類似,集合推導(dǎo)也支持 if 語句進(jìn)行選擇,語法如下:
{expression for item iteratable if condition}
可以認(rèn)為它使用如下代碼創(chuàng)建了一個集合:
s = set()
for item iteratable:
if condition:
s.add(expression)
注意,在第 3 行,只有滿足條件,才會將元素添加到集合中。
2.2 應(yīng)用舉例
- 包含從 0 到 10 之間所有整數(shù)的集合
>>> {i for i in range(10)}
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
- 將集合中的元素乘以 10
>>> set = {1, 2, 3}
>>> {i*10 for i in set}
{10, 20, 30}
- 將列表中所有的字符串變成大寫
>>> set = {'www', 'imooc', 'com'}
>>> {i.upper() for i in set}
{'WWW', 'IMOOC', 'COM'}
- 包含所有的正整數(shù)的集合
>>> set = {-1, 1, -2, 2, -3, 3}
>>> {i for i in list if i > 0}
{1, 2, 3}
- 包含兩個字符的字符串集合
>>> {x + y for x in 'ABC' for y in 'XYZ'}
{'AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ'}
3. 字典推導(dǎo)
3.1 定義
列表推導(dǎo)用于快速生成一個列表,類似的,Python 同時提供了字典推導(dǎo)用于快速生成一個字典,語法如下:
{key:value for item iteratable}
可以認(rèn)為它使用如下代碼創(chuàng)建了一個字典:
dict = {}
for item iteratable:
dict[key] = value
- 在第 1 行,創(chuàng)建一個空的字典
- 在第 2 行,創(chuàng)建一個循環(huán)語句,遍歷 iteratable
- 在第 3 行,在循環(huán)中,向字典添加鍵值對
與列表推導(dǎo)類似,字典推導(dǎo)也支持 if 語句進(jìn)行選擇,語法如下:
{expression for item iteratable if condition}
可以認(rèn)為它使用如下代碼創(chuàng)建了一個集合:
dict = {}
for item iteratable:
if condition:
dict[key] = value
注意,在第 3 行,只有滿足條件,才會將元素添加到字典中。
3.2 應(yīng)用舉例
- 創(chuàng)建從小寫到大寫的映射
>>> list = ['www', 'imooc', 'com']
>>> {i:i.upper() for i in list}
{'www': 'WWW', 'imooc': 'IMOOC', 'com': 'COM'}
- 對字典進(jìn)行篩選
>>> all_students = {'tom': 95, 'jerry': 80, 'mike': 99, 'john': 70}
>>> good_students = {item[0]:item[1] for item in all_students.items() if item[1] > 90}
>>> good_students
{'tom': 95, 'mike': 99}
- 在第 1 行,創(chuàng)建一個包含 4 個學(xué)生的集合,姓名作為鍵,成績作為值
- tom 的成績?yōu)?95 分
- jerry 的成績?yōu)?80 分
- mike 的成績?yōu)?99 分
- john 的成績?yōu)?70 分
- 在第 2 行,在原有的集合中選擇成績大于 90 分的學(xué)生,構(gòu)造一個新的集合
- for item in all_students.items (),遍歷 all_students
- 循環(huán)變量 item 是一個包含兩個元素的元組
- item [0] 是姓名
- item [1] 是成績
- if item [1] > 90,選擇成績大于 90 分
- item [0]:item [1],使用 item [0] 作為鍵,使用 item [] 作為值
- 對字典進(jìn)行篩選
>>> all_students = {'tom': 95, 'jerry': 80, 'mike': 99, 'john': 70}
>>> good_students = {name:grade for name,grade in all_students.items() if grade > 90}
>>> good_students
{'tom': 95, 'mike': 99}
- 這個例子與上個例子完成相同的功能,但是使用更簡潔的語法
- 在第 1 行,創(chuàng)建一個包含 4 個學(xué)生的集合,姓名作為鍵,成績作為值
- tom 的成績?yōu)?95 分
- jerry 的成績?yōu)?80 分
- mike 的成績?yōu)?99 分
- john 的成績?yōu)?70 分
- 在第 2 行,在原有的集合中選擇成績大于 90 分的學(xué)生,構(gòu)造一個新的集合
- for name,grade in all_students.items (),遍歷 all_students
- 循環(huán)變量是一個包含兩個元素的元組,‘name,grade’ 表示該元組
- 使用變量 name 表示該元組的第 0 項
- 使用變量 grade 表示該元組的第 1 項
- if grade > 90,選擇成績大于 90 分
- name:grade,使用 name 作為鍵,使用 grade 作為值
4. 小結(jié)
推導(dǎo)式這種方式能都快速幫我們生成我們想要的列表,集合或者字典等等。極大的加快了我們的開發(fā)速度。假如你是一位測試人員,需要大量的假數(shù)據(jù)來測試程序,這個時候推導(dǎo)式這種方式就很適合你。