Python 列表推導式與字典推導式的實現

在 Python 中推導式是一種非常 Pythonic 的知識,本篇博客將為你詳細解答列表推導式與字典推導式相關的技術知識。

列表推導式

列表推導式可以利用列表,元組,字典,集合等數據類型,快速的生成一個特定需要的列表。

語法格式如下:

[表達式 for 迭代變量 in 可迭代對象 [if 條件表達式]]

if 條件表達式 非必選,學完列表推導式之後,你可以發現它就是 for 循環的一個變種語句,例如咱們現有一個需求是將一個列表中的所有元素都變成原值的 2 倍。

for 循環寫法

my_list = [1,2,3]
new_list = []
for i in my_list:
    new_list.append(i*2)

print(new_list)

列表推導式寫法

nn_list = [i*2 for i in my_list]
print(nn_list)

是不是對比看就是將 for 循環語句做瞭變形之後,增加瞭一個 [],不過需要註意的是,列表推導式最終會將得到的各個結果組成一個新的列表。

再看一下列表推導式語法構成 nn_list = [i*2 for i in my_list] ,for 關鍵字後面就是一個普通的循環,前面的表達式 i*2 其中的 i 就是 for 循環中的變量,也就是說表達式可以用後面 for 循環迭代產生的變量,理解這個內容列表推導式就已經掌握 9 成內容瞭,剩下的是熟練度的問題。

在將 if 語句包含進代碼中,運行之後,你也能掌握基本技巧,if 語句是一個判斷,其中 i 也是前面循環產生的迭代變量。

nn_list = [i*2 for i in my_list if i>1]
print(nn_list)

這些都是一般技能,列表推導式能支持兩層 for 循環,例如下述代碼:

nn_list = [(x,y) for x in range(3) for y in range(3) ]
print(nn_list)

當然如果你想**加密(誰都看不懂你的代碼)**你的代碼,你可以無限套娃下去,列表推導式並沒有限制循環層數,多層循環就是一層一層的嵌套,你可以展開一個三層的列表推導式,就都明白瞭

nn_list = [(x,y,z,m) for x in range(3) for y in range(3) for z in range(3) for m in range(3)]
print(nn_list)

當然在多層列表推導式裡面,依舊支持 if 語句,並且 if 後面可以用前面所有迭代產生的變量,不過不建議超過 2 成,超過之後會大幅度降低你代碼的可閱讀性。
當然如果你希望你代碼更加難讀,下面的寫法都是正確的。

nn_list = [(x, y, z, m) for x in range(3) if x > 1 for y in range(3) if y > 1 for z in range(3) for m in range(3)]
print(nn_list)
nn_list = [(x, y, z, m) for x in range(3) for y in range(3) for z in range(3) for m in range(3) if x > 1 and y > 1]
print(nn_list)
nn_list = [(x, y, z, m) for x in range(3) for y in range(3) for z in range(3) for m in range(3) if x > 1 if y > 1]
print(nn_list)

現在你已經對列表推導式有比較直觀的概念瞭,列表推導式對應的英文是 list comprehension,有的地方寫作列表解析式,基於它最後的結果,它是一種創建列表的語法,並且是很簡潔的語法。

有瞭兩種不同的寫法,那咱們必須要對比一下效率,經測試小數據范圍影響不大,當循環次數到千萬級時候,出現瞭一些差異。

import time
def demo1():
    new_list = []
    for i in range(10000000):
        new_list.append(i*2)

def demo2():
    new_list = [i*2 for i in range(10000000)]
s_time = time.perf_counter()
demo2()
e_time = time.perf_counter()
print("代碼運行時間:", e_time-s_time)

運行結果:

# for 循環
代碼運行時間: 1.3431036140000001
# 列表推導式
代碼運行時間: 0.9749278849999999

在 Python3 中列表推導式具備局部作用域,表達式內部的變量和賦值隻在局部起作用,表達式的上下文裡的同名變量還可以被正常引用,局部變量並不會影響到它們。所以其不會有變量泄漏的問題。例如下述代碼:

x = 6
my_var = [x*2 for x in range(3)]

print(my_var)
print(x)

列表推導式還支持嵌套

參考代碼如下,隻有想不到,沒有做不到的。

my_var = [y*4 for y in [x*2 for x in range(3)]]
print(my_var)

字典推導式

有瞭列表推導式的概念,字典推導式學起來就非常簡單瞭,語法格式如下:
{鍵:值 for 迭代變量 in 可迭代對象 [if 條件表達式]}

直接看案例即可

my_dict = {key: value for key in range(3) for value in range(2)}
print(my_dict)

得到的結果如下:
{0: 1, 1: 1, 2: 1}

此時需要註意的是字典中不能出現同名的 key,第二次出現就把第一個值覆蓋掉瞭,所以得到的 value 都是 1。
最常見的哪裡還是下述的代碼,遍歷一個具有鍵值關系的可迭代對象。

my_tuple_list = [('name', '橡皮擦'), ('age', 18),('class', 'no1'), ('like', 'python')]
my_dict = {key: value for key, value in my_tuple_list}
print(my_dict)

元組推導式與集合推導式

其實你應該能猜到,在 Python 中是具備這兩種推導式的,而且語法相信你已經掌握瞭。不過語法雖然差不多,但是元組推導式運行結果卻不同,具體如下。

my_tuple = (i for i in range(10))
print(my_tuple)

運行之後產生的結果:
<generator object <genexpr> at 0x0000000001DE45E8>

使用元組推導式生成的結果並不是一個元組,而是一個生成器對象,需要特別註意下,這種寫法在有的地方會把它叫做生成器語法,不叫做元組推導式。
集合推導式也有一個需要註意的地方,先看代碼:

my_set = {value for value in 'HelloWorld'}
print(my_set)

因為集合是無序且不重復的,所以會自動去掉重復的元素,並且每次運行顯示的順序不一樣,使用的時候很容易暈掉。

總結

到此這篇關於Python 列表推導式與字典推導式的實現的文章就介紹到這瞭,更多相關Python 列表推導式與字典推導式內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: