天天看點

python的清單生成式

清單生成式是一種基于其他iterable(如集合、元組、其他清單等)建立清單的方法。它還可以用更簡單、更吸引人的文法表示for和if循環。不過,清單生成式比for循環要快得多。

清單生成式的基本結構如下:

python的清單生成式

這看起來很簡單,但在某些情況下可能會變得棘手。在本文中,我們将從一個非常簡單的清單生成式開始,并逐漸增加複雜性。我将清楚地解釋如何表示和生成式高度複雜的清單生成式。

在大多數情況下,清單生成式優先于for和if循環,因為:

  • 它們比for循環快得多
  • 它們被認為比循環和映射函數更具python特性
  • 清單生成式的文法更容易閱讀

我們從一個簡單的例子開始。

words = ['data','science','machine','learning']
      

我們要建立一個清單,其中包含單詞清單中每個單詞的長度。我們使用for循環和清單生成式來執行任務。

# for循環
a = []
for word in words:
   a.append(len(word))

# 清單生成式
b = [len(word) for word in words]

print(f"a is {a}")
print(f"b is {b}")

a is [4, 7, 7, 8]
b is [4, 7, 7, 8]
      

生成式清單文法的最佳方法是比較for和if循環。下圖示範了比較:

python的清單生成式

for循環末尾的表達式放在清單的開頭。

當我們複習這些例子時,會更清楚。讓我們建立一個清單,其中包含單詞清單中長度大于5的項。

# for循環
a = []
for word in words:
   if len(word) > 5:
     a.append(word)

# 清單生成式
b = [word for word in words if len(word) > 5]

print(f"a is {a}")
print(f"b is {b}")

a is ['science', 'machine', 'learning']
b is ['science', 'machine', 'learning']
      

下圖顯示了如何在清單中表示循環中的表達式。

python的清單生成式

與上一個示例一樣,在for循環末尾所做的事情被放在清單的開頭。在這種情況下,我們按原樣處理項。清單生成式的下一部分是循環中的第一個表達式,然後是循環中的第二個表達式。

循環中的邏輯更直覺。是以,與循環相比,清單生成式的結構相對容易掌握。過一段時間,你就不必做一個明确的比較,因為你的大腦已經習慣了。

下一個例子稍微複雜一些。我們要建立一個包含單詞清單項中所有“a”、“e”和“i”字母的清單。此任務涉及嵌套的for和if循環。

# for循環
a = []
for word in words:
  for letter in word:
    if letter in ["a","e","i"]:
       a.append(letter)
      

詳細說明一下文法:反複浏覽單詞表。對于每個項,周遊字元。如果一個字元符合給定的條件,它将被附加到清單a中。

完成相同任務的清單生成式如下。

b = [letter for word in words for letter in word if letter in ["a","e","i"]]
      

我們從for循環中的最後一個表達式開始生成式清單。剩下的部分從循環的開頭開始。下圖說明了每個步驟。

python的清單生成式

結論

清單生成式是一種高效的操作。對于簡單的任務,生成式的文法很容易,在複雜的情況下可能會變得棘手。

如果你很難建立或生成式複雜的清單生成式,請嘗試使用循環編寫。

需要注意的是,清單生成式并不總是最佳選擇。它們将整個輸出清單加載到記憶體中。這對于中小型清單是可以接受的,甚至是可取的,因為它使操作更快。

然而,當我們處理大型清單(例如10億個元素)時,應該避免清單生成式。它可能會導緻你的計算機崩潰,由于記憶體需求量過大。

對于這樣大的清單,一個更好的選擇是使用一個生成器,它實際上不會在記憶體中建立一個大的資料結構。生成器在使用項時建立它們。用完後,生成器會将它們扔掉。生成器不會導緻記憶體問題,但它們比清單生成式相對較慢。