2.12. 迴圈¶
迴圈會重複執行同一段程式碼。Python 有兩種形式:while 只要條件持續為真就會一直執行,而 for 則會走訪序列中的各個項目。
while 會不斷測試一個條件;for 則走訪一個序列直到取盡為止。¶
2.12.1. while 迴圈¶
while 迴圈會在每次迭代前測試其條件,並持續執行主體直到測試結果變為假:
count = 0
while count < 5:
print(count)
count += 1
輸出:
0
1
2
3
4
如果條件在一開始為真且永遠不會變為假,迴圈就會永遠執行下去。while True: 是主迴圈的標準慣用寫法,並以 break 明確地退出:
while True:
step()
if done():
break
2.12.2. for 迴圈¶
for 迴圈會走訪一個可迭代物件的各個項目 -- 清單、tuple、字串、bytes、dict,或任何其他支援迭代的物件:
for fruit in ["apple", "banana", "cherry"]:
print(fruit)
輸出:
apple
banana
cherry
同樣的形式也適用於字串,此時每個項目都是長度為一的字串:
for letter in "OpenMV":
print(letter)
輸出:
O
p
e
n
M
V
直接迭代一個 dict 會依插入順序產生它的鍵:
for key in {"a": 1, "b": 2}:
print(key)
輸出:
a
b
每一輪都會把迴圈變數(fruit、letter、key)繫結到下一個項目。迴圈結束後,該變數仍保留最後一次迭代時的值。
2.12.3. range¶
若要對一個數值範圍進行迴圈,請使用 range():
range(stop)-- 0、1、...、stop - 1。range(start, stop)-- start、start + 1、...、stop - 1。range(start, stop, step)-- 帶有自訂步長(負值則向下計數)。
for i in range(5): # 0, 1, 2, 3, 4
print(i)
for i in range(2, 8, 2): # 2, 4, 6
print(i)
for i in range(10, 0, -1): # 10, 9, ..., 1
print(i)
range() 會惰性地產生數值 -- 它不會在記憶體中建立清單。若要取得實際的 list,請將其包裹起來:list(range(10))。
2.12.4. enumerate¶
當迴圈同時需要索引與項目時,enumerate() 會產生 (index, item) 配對:
for i, name in enumerate(["a", "b", "c"]):
print(i, name)
# 0 a
# 1 b
# 2 c
傳入第二個引數即可讓索引從零以外的值開始:enumerate(items, start=1)。
2.12.5. zip¶
若要同步走訪兩個(或更多)可迭代物件,請使用 zip()。它會在每個位置產生一個 tuple,並在最短的輸入耗盡時停止:
names = ["alice", "bob", "carol"]
scores = [88, 92, 70]
for name, score in zip(names, scores):
print(name, score)
輸出:
alice 88
bob 92
carol 70
2.12.6. 使用 := 的內嵌指派¶
海象運算子 := 是一種既是指派又是運算式的寫法。它會繫結一個名稱,並在同一時間求值為相同的值。在 while 迴圈中,這能把常見的「讀取、檢查、主體」模式收合成一行:
# without walrus
value = next_value()
while value is not None:
process(value)
value = next_value()
# with walrus
while (value := next_value()) is not None:
process(value)
這兩種形式做的事情相同。當指派的重複確實損害了可讀性時,才使用 :=;不要只為了賣弄聰明而使用它。在大多數位置上,括號是必要的,以維持運算式的明確性。