4. 深入了解流程控制¶
除了剛才介紹的 while,Python 擁有在其他程式語言中常用的流程控制語法,並有ㄧ些不一樣的改變。
4.1. if 陳述式¶
或許最常見的陳述式種類就是 if 了。舉例來說:
>>> x = int(input("Please enter an integer: "))
Please enter an integer: 42
>>> if x < 0:
... x = 0
... print('Negative changed to zero')
... elif x == 0:
... print('Zero')
... elif x == 1:
... print('Single')
... else:
... print('More')
...
More
可以有零個或多個 elif 段落,且 else 段落可有可無。關鍵字 elif 只是「else if」的縮寫,並且用來避免過多的縮排。一個 if … elif … elif … 序列可以用來替代其他語言中出現的 switch 或 case 陳述式。
4.2. for 陳述式¶
在 Python 中的 for 陳述式可能不同於在 C 或 Pascal 中所看到的使用方式。與其只能选代 (iterate) 一個等差級數(如 Pascal),或給與使用者定義选代步進方式與結束條件(如 C),Python 的 for 陳述选代任何序列(list 或者字串)的元素,以他們出現在序列中的順序。例如(無意雙關):
>>> # Measure some strings:
... words = ['cat', 'window', 'defenestrate']
>>> for w in words:
... print(w, len(w))
...
cat 3
window 6
defenestrate 12
如果你在迴圈中需要修改一個你正在选代的序列(例如重複一些選擇的元素),那麼會建議你先建立一個序列的拷貝。选代序列並不暗示建立新的拷貝。此時 slice 語法就讓這件事十分容易完成:
>>> for w in words[:]: # Loop over a slice copy of the entire list.
... if len(w) > 6:
... words.insert(0, w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']
With for w in words:, the example would attempt to create an infinite list,
inserting defenestrate over and over again.
4.3. range() 函式¶
如果你需要选代一個數列的話,使用內建 range() 函式就很方便。它可以生成一等差級數:
>>> for i in range(5):
... print(i)
...
0
1
2
3
4
給定的結束值永遠不會出現在生成的序列中;range(10) 生成的 10 個數值,即對應存取一個長度為 10 的序列內每一個元素的索引值。也可以讓 range 從其他數值計數,或者給定不同的級距(甚至為負;有時稱之為 『step』):
range(5, 10)
5, 6, 7, 8, 9
range(0, 10, 3)
0, 3, 6, 9
range(-10, -100, -30)
-10, -40, -70
欲选代一個序列的索引值們,你可以搭配使用 range() 和 len() 如下:
>>> a = ['Mary', 'had', 'a', 'little', 'lamb']
>>> for i in range(len(a)):
... print(i, a[i])
...
0 Mary
1 had
2 a
3 little
4 lamb
然而,在多數的情況,使用 enumerate() 函式將更為方便,詳見迴圈技巧。
如果直接印出一個 range 則會出現奇怪的輸出:
>>> print(range(10))
range(0, 10)
在很多情況下,由 range() 回傳的物件的行為如同一個 list,但實際上它並不是。它是一個物件在你选代時會回傳想要的序列的連續元素,並不會真正建出這個序列的 list,以節省空間。
我們稱這樣的物件為 iterable(可选代的),意即能作為函式、陳述式中能一直獲取連續元素直到用盡的部件。我們已經看過 for 陳述式可做為如此的 iterator(选代器)。list() 函式為另一個例子,他可以自 iterable(可选代物件)建立 list:
>>> list(range(5))
[0, 1, 2, 3, 4]
待會我們可以看到更多函式回傳 iterable 和接受 iterable 為引數。
4.4. break 和 continue 陳述、迴圈內 else 段落¶
The break statement, like in C, breaks out of the innermost enclosing
for or while loop.
迴圈可以帶有一個 else 段落。當迴圈歷遍选代的 list (在 for 中)或條件為偽(在 while 中)時,這個段落會被執行;但迴圈被 break 陳述終止時則不會。底下尋找質數的迴圈即示範了這個行為:
>>> for n in range(2, 10):
... for x in range(2, n):
... if n % x == 0:
... print(n, 'equals', x, '*', n//x)
... break
... else:
... # loop fell through without finding a factor
... print(n, 'is a prime number')
...
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
(沒錯,這是正確的程式碼。請看仔細:else 段落屬於 for 迴圈,並非 if 陳述。)
當 else 段落與迴圈使用時,相較於搭配 if 陳述使用,它的行為與搭配 try 陳述使用時更為相似:try 的 else 段落在沒有任何例外 (exception) 時執行,而迴圈的 else 段落在沒有任何 break 時執行。更多有關 try 陳述和例外的介紹,見處理例外。
continue 陳述,亦承襲於 C 語言,讓迴圈於下個选代起繼續執行:
>>> for num in range(2, 10):
... if num % 2 == 0:
... print("Found an even number", num)
... continue
... print("Found a number", num)
Found an even number 2
Found a number 3
Found an even number 4
Found a number 5
Found an even number 6
Found a number 7
Found an even number 8
Found a number 9
