使用巢狀迴圈列出理解
List Comprehensions 可以使用巢狀的 for
迴圈。你可以在列表推導中編碼任意數量的巢狀 for 迴圈,並且每個 for
迴圈可以具有可選的關聯 if
測試。這樣做時,for
構造的順序與編寫一系列巢狀的 for
語句時的順序相同。列表推導的一般結構如下所示:
[ expression for target1 in iterable1 [if condition1]
for target2 in iterable2 [if condition2]...
for targetN in iterableN [if conditionN] ]
例如,以下程式碼使用多個 for
語句展平列表列表:
data = [[1, 2], [3, 4], [5, 6]]
output = []
for each_list in data:
for element in each_list:
output.append(element)
print(output)
# Out: [1, 2, 3, 4, 5, 6]
可以等效地編寫為具有多個 for
構造的列表理解:
data = [[1, 2], [3, 4], [5, 6]]
output = [element for each_list in data for element in each_list]
print(output)
# Out: [1, 2, 3, 4, 5, 6]
在擴充套件形式和列表理解中,外部迴圈(首先是語句)首先出現。
除了更緊湊之外,巢狀理解也明顯更快。
In [1]: data = [[1,2],[3,4],[5,6]]
In [2]: def f():
...: output=[]
...: for each_list in data:
...: for element in each_list:
...: output.append(element)
...: return output
In [3]: timeit f()
1000000 loops, best of 3: 1.37 µs per loop
In [4]: timeit [inner for outer in data for inner in outer]
1000000 loops, best of 3: 632 ns per loop
上面函式呼叫的開銷大約是 140ns 。
內聯 if
s 巢狀類似,可能出現在第一個 for
之後的任何位置:
data = [[1], [2, 3], [4, 5]]
output = [element for each_list in data
if len(each_list) == 2
for element in each_list
if element != 5]
print(output)
# Out: [2, 3, 4]
但是,為了便於閱讀,你應該考慮使用傳統的 for 迴圈。當巢狀深度超過 2 級時,和/或理解的邏輯過於複雜時尤其如此。多個巢狀迴圈列表理解可能容易出錯或者會產生意外結果。