理解 Python 3 中的列表理解

介紹

列表理解提供了一種簡潔的方法來基於現有列表創建列表。使用列表理解時,可以通過利用任何可迭代對象,包括字符串元組,來構建列表。

語法上,列表理解由包含表達式的可迭代對象組成,後跟一個for子句。這之後可以跟隨額外的forif子句,因此熟悉for循環條件語句將有助於更好地理解列表理解。

資料型別 和其他連續型資料的建立,列表理解提供了一種替代語法。儘管其他迭代方法,如 for 循環,也可以用於創建列表,但列表理解可能更受歡迎,因為它們可以限制程序中使用的行數。

先決條件

您應該已經安裝了 Python 3,並在您的計算機或服務器上設置了一個編程環境。如果您尚未設置編程環境,您可以參考安裝和設置指南,為適用於您操作系統的本地編程環境或服務器上的編程環境進行設置(Ubuntu、CentOS、Debian等)。本地編程環境 或者 適用於您服務器的編程環境

列表理解

在 Python 中,列表理解的構造方式如下:

資訊: 若要跟隨本教程中的示例代碼,請在本地系統上運行python3命令打開Python交互式shell。然後,您可以通過在>>>提示之後添加它們來複製、粘貼或編輯示例。

list_variable = [x for x in iterable]

A list, or other iterable, is assigned to a variable. Additional variables that stand for items within the iterable are constructed around a for clause. The in keyword is used as it is in for loops, to iterate over the iterable.

讓我們看一個根據字符串創建列表的示例:

shark_letters = [letter for letter in 'shark']
print(shark_letters)

在這裡,將新列表分配給變量shark_letters,並使用letter代表可迭代字符串'shark'中包含的項目。

為了確認新列表shark_letters的外觀,我們要求打印它並收到以下輸出:

Output
['s', 'h', 'a', 'r', 'k']

我們用列表理解創建的列表由字符串'shark'中的項目組成,即每個字母一個字符串。

列表理解可以重寫為for循環,但不是每個for循環都能重寫為列表理解。

使用我們上面創建shark_letters列表的列表理解,讓我們將其重寫為for循環。這可能有助於我們更好地理解列表理解的工作原理。

shark_letters = []

for letter in 'shark':
    shark_letters.append(letter)

print(shark_letters)

在使用 for 循環創建列表時,指定給列表的變量需要初始化為一個空列表,就像我們代碼塊的第一行一樣。然後,for 循環遍歷項目,在可迭代字符串 'shark' 中使用變量 letter。在 for 循環內部,字符串中的每個項目都會使用 list.append(x) 方法添加到列表中。

將列表理解重寫為 for 循環會給我們提供相同的輸出:

Output
['s', 'h', 'a', 'r', 'k']

列表理解可以重寫為 for 循環,有些 for 循環可以重寫為列表理解,以使代碼更加簡潔。

使用條件與列表理解

列表理解可以利用條件語句來修改現有列表或其他順序數據類型,在創建新列表時進行修改。

讓我們看一個在列表理解中使用 if 語句的例子:

fish_tuple = ('blowfish', 'clownfish', 'catfish', 'octopus')

fish_list = [fish for fish in fish_tuple if fish != 'octopus']
print(fish_list)

列表推导式使用元组fish_tuple作为新列表fish_list的基础。关键词forin被使用,就像上面的部分一样,并且现在添加了一个if语句。if语句表示只添加那些不等于字符串'octopus'的项目,因此新列表只接受元组中与'octopus'不匹配的项目。

当我们运行时,我们会注意到fish_list包含与fish_tuple相同的字符串项目,除了字符串'octopus'已被省略:

Output
['blowfish', 'clownfish', 'catfish']

因此,我们的新列表包含原始元组的每个项目,除了由条件语句排除的字符串。

我们将创建另一个示例,使用数学运算符整数range()序列类型

number_list = [x ** 2 for x in range(10) if x % 2 == 0]
print(number_list)

正在创建的列表number_list将填充为从0到9的每个项目的平方值如果该项目的值可被2整除。输出如下:

Output
[0, 4, 16, 36, 64]

將列表理解拆解一下,讓我們想想如果我們只呼叫 x for x in range(10) 會打印出什麼。我們的小程式和輸出將如下所示:

number_list = [x for x in range(10)]
print(number_list)
Output
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

現在,讓我們添加條件語句:

number_list = [x for x in range(10) if x % 2 == 0]
print(number_list)
Output
[0, 2, 4, 6, 8]

這個 if 語句將最終列表中的項目限制為只包括可以被2整除的項目,省略了所有的奇數。

最後,我們可以添加運算符,使每個 x 的平方:

number_list = [x ** 2 for x in range(10) if x % 2 == 0]
print(number_list)

因此,先前列表中的每個數字 [0, 2, 4, 6, 8] 現在都被平方了:

Output
[0, 4, 16, 36, 64]

您也可以用列表理解來複製嵌套的 if 語句

number_list = [x for x in range(100) if x % 3 == 0 if x % 5 == 0]
print(number_list)

在這裡,列表理解首先會檢查數字 x 是否可以被3整除,然後檢查 x 是否可以被5整除。如果 x 同時滿足這兩個條件,它將被打印,輸出結果是:

Output
[0, 15, 30, 45, 60, 75, 90]

條件 if 語句可用於控制新列表的生成中包含來自現有序列的哪些項目。

列表理解中的嵌套循環

嵌套循环可以用于在我们的程序中执行多次迭代。

这次,我们将审查现有的嵌套for循环结构,并逐步向列表推导式迈进。

我们的代码将创建一个新列表,该列表遍历2个列表,并根据它们执行数学运算。以下是我们的嵌套for循环代码块:

my_list = []

for x in [20, 40, 60]:
	for y in [2, 4, 6]:
		my_list.append(x * y)

print(my_list)

当我们运行此代码时,我们会收到以下输出:

Output
[40, 80, 120, 80, 160, 240, 120, 240, 360]

此代码将在每次迭代中将第一个列表中的项与第二个列表中的项相乘。

为了将其转换为列表推导式,我们将每行代码压缩为一行,以x * y操作开始。然后是外部for循环,然后是内部for循环。我们将在列表推导式下面添加一个print()语句,以确认新列表与我们使用嵌套for循环块创建的列表相匹配:

my_list = [x * y for x in [20, 40, 60] for y in [2, 4, 6]]
print(my_list)
Output
[40, 80, 120, 80, 160, 240, 120, 240, 360]

我们的列表推导式将嵌套的for循环压缩为一行代码,同时仍然创建与分配给my_list变量相同的确切列表。

列表推导式为我们提供了一种简洁的方法来创建列表,使我们能够将几行代码凝练为一行。然而,值得注意的是,代码的可读性应始终优先考虑,因此当列表推导式变得过长或难以处理时,最好将其拆分为循环。

結論

列表理解允許我們將一個列表或其他序列轉換為新列表。它們提供了一種簡潔的語法來完成這個任務,限制我們的代碼行數。

列表理解遵循集合生成器表示法或集合理解的數學形式,因此對具有數學背景的程序員可能特別直觀。

雖然列表理解可以使我們的代碼更加簡潔,但重要的是要確保我們的最終代碼盡可能易讀,因此應避免非常長的單行代碼,以確保我們的代碼用戶友好。

Source:
https://www.digitalocean.com/community/tutorials/understanding-list-comprehensions-in-python-3