再論Python迴圈 — While Loop

Sean Yeh
Python Everywhere -from Beginner to Advanced
8 min readAug 4, 2020

--

前文曾經提及,while迴圈會在條件為True的狀況下,重複執行內部的程式區塊內容。這裡要再進一步的說明while迴圈。用白話文來說,就是『在某種條件下的特定期間內』的意思。例如:在旅遊的期間、在上班的期間、在疫情的期間等等。

看看下面while迴圈的例子:

首先第一行我們指定變數x的值為0,這是一個起始數字。

在第二行,當x小於五的狀態下,在螢幕顯示結果(第三行)後,並且將變數x的值加1。(第四行)。最後當迴圈執行完畢後,在螢幕顯示變數x最後的值(第五行)。

x = 0while x < 5:    print("第 {} 次執行 while 迴圈:".format(str(x+1)))    x= x + 1print("總共執行 while 迴圈共:{} 次".format(str(x)))

執行結果為五次:

在函式中的迴圈

我們可以把while迴圈寫在一個函式裡面:

def attempts(num):    x = 1    while x <= num:        print("第一次 " + str(x))        x += 1    print("執行完畢")

透過attempts(數字)來呼叫,例如我們放入10。

attempts(10)

倒數計時迴圈

設計一個count_down函式,函式裡面使用while迴圈倒數計時。只要輸入欲開始倒數的數字,程式就會自動從開始數字倒數計算到零為止。

def count_down(start):    curr = start    while (curr > 0):        print("倒數",curr)        curr -= 1    print("0,時間到!")count_down(10)

從上面三個例子可以發現,當我們使用迴圈之前,必須注意起始變數(例如 x=0)是否已經正確設定。

我們一般在剛開始寫while迴圈時,常常會忘記設定起始變數,結果就會導致NameError。解決這個問題,就是要在迴圈開始前設定起始變數。像前面的例子一樣 x = 0、x = 1或者是curr = start都是設定起始變數的方法。

另外一個常見的錯誤是設定了錯誤的起始變數。例如下面的例子:

x =1sum = 0while x < 10:    sum += x    x += 1
product = 1while x < 10: product = product * x x += 1
print(sum, product)

在這個例子裡面,結果是45與1。為什麼第二個數字是1?

因為第一組迴圈執行到最後,x 已經為10。當到了要執行第二組迴圈時,由於 x 已經為10 ,導致迴圈沒有啟動執行,product即維持原來的數字1。

像這樣的錯誤我們很難找到,因為Python本身不會顯示錯誤訊息。若要解決這個問題,我們需要重新將 x 設定為1,才可以正確的執行第二組迴圈。

因此只要迴圈的條件為True,主體程式就會反覆執行,當條件為False時,while迴圈會終止。如果條件一開始就是False的話,主體程式就完全不會執行。如果起始變數在程式的開始與中間都會被使用的話,在中間的時候必須注意起始變數的值是否已經被改變了。

無限迴圈

看下面的式子:

while x % 2 == 0:    x = x /2

如果這這裡的x為0,會發生什麼情形?

上面的程式碼執行的結果會出現像never ending story 般的無限循環迴圈。無限的迴圈可能會讓你的電腦因資源的耗盡而當掉。要修正這個問題,我們可以加上一行判斷,來對 x 值進行判斷。

if x !=0:    while x % 2 == 0:        x = x /2

上面的if statement 可以確保只有在x值不是0的狀況下,才會執行迴圈。

我們再看一個例子:

我們希望這個程式可以產生一組從開始到結束數字的迴圈。如果你執行下面的程式碼,應該會得到一個無限迴圈。

def print_range(start, end):    n = start    while n <= end:        print(n)print_range(1, 5)

要怎麼修改才不會發生無限迴圈?

def print_range(start, end):    n = start    while n <= end:        print(n)        n += 1print_range(1, 5)

答案是在while迴圈裡面加上 n += 1。在每次迴圈執行完畢的時候,讓n的數字比目前大1,這樣子就不會出現無限迴圈的現象了。

用break來阻斷無限迴圈

無限迴圈也不是完全不可以使用。如果你希望迴圈在某個情況下停止,但是又不確定那個情況會在什麼時候發生,這時候可以使用無限迴圈加上一個break陳述來實現這個功能。

換句話說,在迴圈中加入break,也是避免while迴圈變成無限循環的方式之一。

while True:    do_something()    if requested_to_stop()        break

例如下面的程式碼:程式碼會一直不斷的執行直到使用者輸入q才會跳出迴圈。

While True:    action = input("請填寫一個句子或鍵入q 結束對話")    if action =="q":        break    print(action)

文字對話介面

這個方式很適合用來設計操作對話的介面。下面是對話介面的簡單示範:

def display_menu():
print('OO會員管理系統')
print('-'*40)
print('1. 輸入會員資料')
print('2. 輸入購買事件')
print('3. 輸入退貨事件')
print('4. 輸入換貨事件')
print('5. 顯示會員購買明細')
print('0. 結束程式')
print('-'*40)
# 主程式
def main():
while True:
display_menu()
user_choice = input('請輸入選項: ')

if user_choice == '1':
print('您選擇的是:輸入會員資料')
elif user_choice == '2':
print('您選擇的是:輸入購買事件')
elif user_choice == '3':
print('您選擇的是:輸入退貨事件')
elif user_choice == '4':
print('您選擇的是:輸入換貨事件')
elif user_choice == '5':
print('您選擇的是:顯示會員購買明細')
else:
break

#主程式####
if __name__ == "__main__":
main()

猜數字遊戲

也可以用來製作簡單的遊戲。下面是一個簡單的猜數字遊戲。使用者可以透過對話方式,輸入1到10的數字來猜。這裡的設計是要強制使用者猜數字,直到猜對為止我們使用while迴圈。如果你希望使用者只能猜某個特定次數的話(例如猜5次),可以改用for迴圈來實現。

import random  random_number = random.randint(1,10)while True:    
user_guess = input("請從 1 到 10 中間選一個數字 ")
user_guess = int(user_guess)
if user_guess < random_number:
print("你猜的數字太小了")
elif user_guess > random_number:
print("你猜的數字太大了")
else:
print("恭喜,猜對了")
play_again = input("要不要再試一次? (y/n) ")
if play_again =="y":
random_number = random.randint(1,10)
user_guess = None
else:
print("結束遊戲,歡迎下次再來")
break

在製作猜數字遊戲時,必須先匯入random套件,這個套件可以隨機產生數字。我們在這裡使用randint方法從1到10中間隨機產生一個數字( random.randint(1,10) )。

接者就是比較使用者輸入的數字( user_guess )與隨機產生的數字(random_number)之間的大小。比較前,記得先將使用者輸入的字串轉換為數字( user_guess = int(user_guess) )。使用while迴圈,當條件為True時,不斷的循環直到猜到並且選擇 n 結束遊戲為止,在結束遊戲的地方我們使用break來跳出迴圈。

總結來說,迴圈可以用在很多地方,在使用上也需要注意無限迴圈的情形。程式會產生預期以外的無限迴圈,大都是迴圈執行條件沒有隨著迴圈的執行而發生變化。在撰寫程式的時候要特別注意。

--

--

Sean Yeh
Python Everywhere -from Beginner to Advanced

# Taipei, Internet Digital Advertising,透過寫作讓我們回想過去、理解現在並思考未來。並樂於分享,這才是最大贏家。