Python 初學第四講 — 迴圈

迴圈幫我們一次解決重複的事

陳子晴
ccClub
10 min readNov 13, 2018

--

前面介紹了 Python 中的條件判斷,使程式能夠判斷不同條件來執行不同的敘述。

在處理資料的時候,時常會需要重複執行某些相同的步驟;而迴圈 (loop) 的作用是讓指定的某段敘述在條件符合的情況下一直重覆執行,是程式設計中很重要的一種控制結構。我們可以利用迴圈來進行重覆性的資料輸入、處理與輸出。

for-loop

1.單層 for-loop

forin 是 Python 的關鍵字,這兩個關鍵字之間會放我們自訂的變數,而 in的後面則可接一個序列 (Sequence),迴圈會依序從序列 (例如: 一連串清單資料,一組數字或一個名單) 裡取得元素,並將元素指派給前面自訂的變數,然後執行迴圈裡的內容:

for x in sequence:
# 放要執行的東西

在 Python 中有個叫做串列 (list) 的資料結構,用法跟在其它程式語言的陣列(Array) 差不多,我們可以用它來儲存序列式的資料,關於 list 進一步的介紹我們在下一講會和大家詳細說明。

list 使用中括號 [] 將數字、文字等元素包起來。
例如,使用 [1, 2, 3, 4, 5]這樣的語法即可建立內含1、2、3、4、5 共 5 個元素的 list。下面是一個使用 for-loop 將 list 中的序列性資料逐一列印出來的例子:

sequences = [0, 1, 2, 3, 4, 5]
for i in sequences:
print(i)

執行結果如下:

利用for-loop列印出一筆序列資料中的所有元素

串列 (list) 裡的元素並不限於數字,也可以是文字或物件。

在下例中,list 便是由文字構成的。

程式中用到的 len()是 Python 的內建函式,其作用是傳回 list 的長度;
theBeatles[i]這樣的語法,則是指利用索引運算子 []來取得串列中索引為 i 的元素:

theBeatles = ['John Lennon', 'Paul McCartney', 'Ringo Starr', 'George Harrison']
for i in range(len(theBeatles)):
print(theBeatles[i])

執行結果如下:

當然,上面的程式也可以完全不用到 len()函式和索引運算子,程式反而顯得更為簡潔而且容易閱讀:

theBeatles = ['John Lennon', 'Paul McCartney', 'Ringo Starr', 'George Harrison']
for beatle in theBeatles:
print (beatle)

Python 的 for-loop 語法有三個需要注意的重點:初始值、終止值,以及每次執行迴圈後控制變數遞增或是遞減的變化。

在 Python 程式語言中,range()函式可以很有效率地協助我們創建一個整數序列,用法為 (起始值, 終止值, 遞增(減)值),例如:

range(10):產生從0到9的整數序列。

range(1, 11):產生從1到10的整數序列(未指定遞增值的情況下,其遞增值預設為1)。

range(0, 10, 2):產生從0, 2, 4, 6, 8的整數序列(遞增值為2)。

簡單來說,for迴圈以固定數量的變數作為控制條件的依據,而利用range() 函式,可以很方便的建立出一個整數序列,讓程式依照序列裡的數值來執行迴圈裡的內容:

for i in range(10):
print(i, end=" ")

print() #換行
for i in range(20, 2, -2):
print(i, end=" ")

執行結果如下:

利用range()來產生for-loop的控制變數

2. 巢狀for-loop

巢狀迴圈的特性是在迴圈裡面又包覆著其他的迴圈。

從外層迴圈來看,內層迴圈只是外層迴圈內所要執行的一段程式敘述而已;因此外層迴圈每動作一次,內層迴圈就會把整個迴圈執行一遍,執行完畢後才跳回到外層迴圈準備下一次的動作。

前面所提到的單層 for-loop 適用於單一控制變數的反覆計算,這個控制變數的意義可以是迴圈執行的次數或是任意連續變化的物理量。

如果今天我們所要處理的問題具有重複執行某段敘述的特性,而且這些敘述受到兩個 (或兩個以上) 的變數來分別控制其變化,此時使用巢狀迴圈的技巧來撰寫功能需求會是最適合的方式。

九九乘法的資料共有九列九行資料,其呈現的樣子為為二維平面空間,所以這是一個使用兩層巢狀迴圈結構來撰寫的良好案例:

for i in range(1, 10):
for j in range(1, 10):
if j == 9:
print("\t", i*j) # j == 9時,換行
else:
print("\t", i*j, end = '') # j < 9時,不換行

執行結果如下:

使用兩層巢狀迴圈結構來輸出九九乘法的資料

3. break 和 continue

迴圈的結束分為規則的結束和不規則的結束。
規則的結束方式是當迴圈的判斷條件不再符合時,迴圈自然結束;而不規則的迴圈結束則是在迴圈自然結束前,我們已經得到想要的運算結果,利用強制中斷的方式來結束迴圈。

Python 提供了兩個指令,用來強制迴圈流程中斷或跳過迴圈中的某些敘述:

  1. break:中斷迴圈的執行並跳脫迴圈結構,繼續執行迴圈外的敘述。
  2. continue:不會讓迴圈結束;只跳過迴圈內 continue 後面的剩餘敘述,接著繼續執行下一次的迴圈運作。

也就是說,當程式執行到迴圈結構內的 break 敘述時,break 敘述會中斷迴圈的執行,並且跳出迴圈結構,開始向下執行迴圈結構外的敘述。
因此,對於巢狀迴圈,若最內圈執行到 break 敘述時,則只會使最內圈的迴圈結束,而不是跳脫到整個巢狀迴圈結構外。

continue 敘述與 break 敘述之間有些相似,但它不會讓迴圈結束。
continue 敘述會讓程式跳出最靠近的這層迴圈,不再向下執行之後的敘述,然後繼續執行下一步的迴圈運作。
因此它的目的是為了讓程式不執行迴圈結構內的某些敘述而已。

關於 break 敘述和 continue 敘述的差異示意圖如下:

break與continue的差別

接下來這個程式的目的是利用 for-loop 逐一列印出字串中的字元內容,但當迴圈的變數變為字元 "u" 時,則中斷迴圈的執行,立刻跳脫迴圈:

for i in "Hey Jude":
if i == "u":
break
print(i)

執行結果如下:

利用 break 敘述中斷迴圈執行,跳脫這個迴圈

同樣一個 for-loop 程式,我們將 break 改成 continue,其餘不變;當迴圈的變數變為字元 "u" 時,程式只是跳過一次的迴圈循環,不執行 continue 下一行的 print 敘述;但迴圈並未結束,會在更新變數後繼續執行下去:

for i in "Hey Jude":
if i == "u":
continue
print(i)

執行結果如下:

當變數等於字元”u”時,不再執行 continue 下面的 print 敘述,繼續往下執行下一次迴圈。

while loops

原則上,透過 for-loop 敘述可以處理的問題大概都可以改用 while-loop 來處理;但即使兩者之間的特性如此類似,其適用範圍還是有一點差別的。

一般而言,for-loop 比較適用在「已知迴圈數」的問題,而 while-loop 則適用在「無法預知迴圈數」的問題上。

當程式需要不斷地重覆某些運算,一直到出現指定的特殊狀況時才停止,這種情形就比較適合用 while-loop 來實現。

while-loop 在執行其內部敘述之前,都會先檢查條件判斷式,如果其判斷值為真 (True),則執行迴圈內部的敘述;否則就結束 while-loop。

例如兩個人玩猜數字遊戲,甲方心中默想一個數讓乙方去猜,甲方就乙方所猜的數字口頭提示「再大一點」或「再小一點」,直到乙方猜中甲方心中默想的特定數字才停止,這樣的遊戲就屬於無法預知迴圈數的問題,相較於 for-loop ,此問題會更適合使用 while-loop 來實現。

while-loop 的語法如下:

while test_expression:
Body of while

若我們要產生一筆 1, 2, 3, …, 10 的序列,用 while-loop 可以這樣寫:

i = 1
while i <= 10:
print(i, end=" ")
i = i + 1

執行結果如下:

利用 while-loop 產生一筆序列資料

利用 while-loop 計算 1 加到 10 的和,並將每次累加之後的值列印出來:

sum = 0
i = 1
while i <= 10:
sum = sum + i
i = i + 1
print(sum, end= " ")

執行結果如下:

利用while-loop計算1加到10的和

我們也可以利用 break 敘述來中斷 while-loop 的執行。在本例中,while 後面的判斷值為 1,代表迴圈永遠成立,會一直執行下去。但我們在迴圈內部加上 if 敘述的判斷條件和 break 敘述,讓迴圈可以在特定情況下結束執行。例如:

sequences = [0, 1, 2, 3, 4, 5]
i = 0
while 1: #判斷條件值為1, 代表迴圈永遠成立
print(sequences[i], end = " ")
i = i + 1
if i == len(sequences):
print("No elements left.")
break

執行結果如下:

利用if敘述的判斷條件和break來中斷while-loop的執行

Example 1 : 列印 1, 2, 3, …, 10的序列,但利用continue跳過 4 這個數字:

i = 0
while i < 10:
i = i + 1
if i == 4:
continue
print (i, end = " ")

執行結果如下:

列印1, 2, …, 10的序列,但利用continue跳過4"這個數字

Example 2 : 列印 9, 8, 7, …, 0的序列,但利用continue跳過 4 這個數字:

i = 10
while i > 0:
i = i - 1
if i == 4:
continue
print(i, end = " ")

執行結果如下:

列印9, 8, 7,…, 0的序列,但利用continue跳過4"這個數字

透過合理的使用條件與迴圈,就能夠寫出很多很有用的程式了!

我們是 ccClub 團隊,致力於讓 Python 成為大家的第二外語,希望能用淺顯易懂、循序漸進的方式,帶領新手一步步跨入程式設計的世界。如果你喜歡這篇文章,請給我們 1~10 個掌聲。
如果你喜歡「Python初學」的教學系列文,請給我們 11 個以上的掌聲。


Facebook: ccClub Python讀書會

--

--