1. 程式人生 > 其它 >Python--使用者輸入和while迴圈

Python--使用者輸入和while迴圈

Python--使用者輸入和while迴圈

目錄
大多數程式只在就解決終端使用者的問題,為此通常需要從使用者那裡獲取一些新資訊。例如,假設有人要判斷自己是否到了投票年齡。要編寫回答這個問題的程式,就需要知道使用者的年齡,才能給出答案。因此,這種程式需要讓使用者輸入
年齡,再將其與投票年齡進行比較,以判斷使用者是否到了投票年齡,從而給出結果。
接下來,你將學習如何接受使用者輸入,以便程式進行比較。程式需要一個名字時,你需要提示使用者輸入該名字;程式需要一個名單時,你需要提示使用者輸入一系列名字。為此,你將使用函式input()。
你還講學習如何讓程式不斷地執行,以便使用者根據需要輸入資訊,並在程式中使用這些資訊。為此,你將使用while迴圈讓程式不斷執行,直到指定的條件不滿足為止。
通過獲取使用者輸入並學會控制程式的執行時間,你就能編寫出互動式程式。

一、函式input()的工作原理

函式input()讓程式暫停執行,等待使用者輸入一些文字。獲取使用者輸入後,Python將其賦給一個變數,以方便使用。
例如,下面的程式讓使用者輸入一些文字,再將這些文字呈現給使用者:

函式input()接受一個引數——要向用戶顯示的提示(prompt)

或說明,讓使用者知道該如何做。在本例中,Python執行第一行程式碼時,使用者將看到提示Tell me something, and I will repeat it back to you: 。程式等待使用者輸入,並在使用者按回車鍵後繼續執行,輸入被賦給變數message,接下來的print(message)將輸入程式給使用者。

注意:
Sublime Text等眾多編輯器不能執行提示使用者輸入的程式。你可以使用Sublime Text來編寫提示使用者輸入的程式,但必須從終端執行它們。

1. 編寫清晰的程式

每當使用函式input()時,都應指定清晰易懂的提示,準確地指出希望使用者提供什麼樣的資訊——指出使用者應該輸入何種資訊的任何提示都行,如下所示:

通過在提示末尾(這裡是冒號後面)包含一個空格,可將提示與使用者輸入分開,讓使用者清楚地知道其輸入始於何處。

有時候,提示可能超過一行。例如,你可能需要指出獲取特定輸入的原因。在這種情況下,可將提示賦給一個變數,再將該變數傳遞給函式input()。這樣,即便提示超過一行,input()語句也會非常清晰。

本例演示了一種建立多行字串的方式。第一行將訊息的前半部分賦給變數prompt中。在第二行中,運算子+=在前面賦給變數prompt的字串末尾附加一個字串。

最終的提示佔據兩行,且問好後面有一個空格,這也是為了使其更加清晰:

2. 使用int()來獲取數值輸入

使用函式input()時,Python將使用者輸入解讀為字串。請看下面讓使用者輸入年齡的直譯器會話:

使用者輸入的是數21,但我們請求Python提供變數age的值時,它返回的是'21'——使用者輸入數值字串表示。我們怎麼知道Python將輸入解讀成了字串呢?因為這個數用引號括起了。如果只想列印輸入,這一點問題都沒有;但如果試圖將輸入作為數來使用,就會引發錯誤:

試圖將輸入用於數值比較時,Python會引發錯誤,因為它無法將字串和整數進行比較:不能將賦給age的字串'28'與數值18進行比較。
未解決這個問題,可使用函式int(),它讓Python將輸入視為數值。函式int()將數的字串表示轉換為數值表示,如下所示:

在本例中,使用者根據提示輸入28後,Python將這個數解讀為字串,但隨後int()將這個字串轉換為數值表示。這樣Python就能執行條件測試了:將變數age(它現在表示的是數值28)同18進行比較,看它是否大於或等於18。測試結果為True。

如何在實際程式中使用函式int()呢?請看下面的程式,它判斷一個人是否滿足坐過山車的身高要求:

在此程式中,為何可以將height同48進行比較呢?因為在比較前,height = int(height)將輸入轉換成了數值表示。如果輸入的數大於或等於48,就指出使用者滿足身高要求:

將數值輸入用於計算和比較前,務必將其轉換為數值表示。

3. 求模運算子

處理數值資訊時,求模運算子(%)是個很有用的工具,它將兩個數相除並返回餘數:

求模運算子不會指出一個數是另一個數的多少倍,只指出餘數是多少。
如果一個數可被另一個數整除,餘數就為0,因此求模運算將返回0.可利用這一點來判斷一個數是奇數還是偶數:

偶數都能被2整除,因此如果對一個數和2執行求模運算的結果為0,即number % 2 == 0,那麼這個數就是偶數;否則就是奇數。

二、while迴圈簡介

for迴圈用於針對集合中的每個元素都執行一個程式碼塊,而while迴圈則不斷執行,直到指定的條件不滿足為止。

1. 使用while迴圈

可使用while迴圈來數數。例如,下面的while迴圈從1數到5:

在第一行,將1賦給變數current_number,從而指定從1開始數。將接下來的while迴圈設定成:只要current_number小於或等於5,就接著執行這個迴圈。迴圈中的程式碼列印current_number的值,再使用程式碼current_number += 1(程式碼current_number = current_number + 1的簡寫)將其值加1。
只要滿足條件current_number <= 5,Python就接著執行這個迴圈。因為1小於5,所以Python列印1並將current_number加1,使其為2,;因為2小於5,所以Python列印2並將current_number加1,使其為3;以此類推。一旦current_number大於5,迴圈就將停止,整個程式也將結束。

你每天使用的程式很可能就包含while迴圈。例如,遊戲使用while迴圈,確保在玩家想玩時不斷執行,並在玩家想退出時停止執行。如果程式在使用者沒有讓它停止時停止執行,或者在使用者要退出時還繼續執行,那就太沒有意思了。因此,while迴圈很有用。

2. 讓使用者選擇何時退出

可以使用while迴圈讓程式在使用者願意時不算執行,如下面的程式所示,我們在其中定義了一個退出值。只要使用者輸入的不是這個值,程式就將接著執行:

首先定義了一條提示資訊,告訴使用者有兩個選擇:要麼輸入一條訊息,要麼輸入退出值(這裡為'quit')。接下來,建立變數message,用於記錄使用者輸入的值。我們將變數message的初始值設定為空字串"",讓Python首次執行while程式碼行時由可供檢查的東西。Python首次執行while語句時,需要將message的值與'quit'進行比較,但此時使用者還沒有輸入。如果沒有可供比較的東西,Python將無法繼續執行程式。為解決這個問題,必須給變數message指定初始值。雖然這個初始值只是一個空字串,但符合要求,能夠讓Python直行while迴圈所需的比較。只要message的值不是'quit',這個迴圈就會不斷執行。
首次遇到這個迴圈時,message是一個空字串,因此Python進入該迴圈。執行到程式碼行message = input(prompt)時,Python顯示提示訊息,並等待使用者輸入。不管使用者輸入時什麼,都將賦給變數message並打印出來。接下來,Python重新檢查while語句中的條件。只要使用者輸入的不是單詞'quit',Python就會再次顯示提示訊息並等待使用者輸入。等到使用者終於輸入'quit'後,Python停止執行while迴圈,整個程式也到此結束:

這個程式很好,唯一美中不足的是,它將單詞'quit'也作為一條訊息列印了出來。為修復這種問題,只需要一個簡單的if測試:

現在,程式在顯示訊息前將做簡單的檢查,僅在訊息不是退出值時才打印它:

3. 使用標誌

在前一個示例中,我們讓程式在滿足指定條件時指定特定的任務。但在更復雜的程式中,很多不同的時間會導致程式停止執行,在這種情況下,該怎麼辦呢?
例如,有多種事件可能導致遊戲結束,如玩家失去所有飛船、時間已用完,或者要保護的城市被全部摧毀。導致程式結束的時間有很多時,如果在一條while語句中檢查所有這些條件,將既複雜又困難。
在要求很多條件都滿足才繼續執行的程式中,可定義一個變數,用於判斷整個程式是否處於活動狀態。這個變數稱為標誌(flag),充當程式的交通訊號燈。可以讓程式在標誌位True時繼續執行,並在任何事件導致標誌的值為False時讓程式停止執行。這樣,在while語句中就只需檢查一個條件:標誌的當前值是否為True。然後將所有其他測試(是否發生了應將標誌設定為False的事件)都放在其他地方,從而讓程式更整潔。
下面在前一節的程式中新增一個標誌。將其命名為active(你可給它指定任何名稱),用於判斷程式是否應繼續執行:

將變數active設定為True,讓程式最初處於活動狀態。這樣做簡化了while語句,因為不需要在其中做任何比較————相關的邏輯由程式的其他部分處理。只要變數active為True,迴圈就將繼續執行。
在while迴圈中,在使用者輸入後使用一條if語句來檢查變數message的值,如果使用者輸入的是'quit',就將變數active設定為False。這將導致while迴圈不再繼續執行。如果使用者輸入的不是'quit',就將輸入作為一條訊息打印出來。
這個程式的輸出與前一個示例相同。前一個示例將條件測試直接放在了while語句中。而這個程式則使用一個標誌來指出程式是否處於活動狀態。這樣,如果要新增測試(如elif語句)以檢查是否發生了其他導致active變為False的事件,就會很容易。在複雜的程式(如很多事件會導致程式停止執行的遊戲)中,標誌很有用:在任意一個事件導致活動標誌變為False時,主遊戲迴圈將退出,此時可顯示一條遊戲結束訊息,並讓使用者選擇是否要重新玩。

4. 使用break退出迴圈

要立即退出while迴圈,不再執行迴圈中餘下的程式碼,也不管條件測試的結果如何,可使用break語句。break語句用於控制程式流程,可用來控制哪些程式碼行將執行、哪些程式碼行不執行,從而讓程式按你的要求執行你要執行的程式碼。
例如,來看一個讓使用者指出他到過哪些地方到的程式。在這個程式中,可在使用者輸入'quit'後使用break語句立即退出while迴圈:

while True打頭的迴圈將不斷執行,直到遇到break語句。這個程式中的迴圈不斷讓使用者輸入他到過的城市的名字,直到使用者輸入'quit'為止。使用者輸入'quit'後,將執行break語句,導致Python退出迴圈:

注意在任何Python迴圈中都可使用break語句。例如,可使用break語句來退出遍歷列表或字典的for迴圈。

5. 在迴圈中使用continue

要返回迴圈開頭,並根據條件測試結果決定是否繼續執行迴圈,可使用continue語句,它不像break語句那樣不再執行餘下的程式碼並退出整個迴圈。例如,來看一個從1數到10但只打印其中迴圈的迴圈:

首先將current_number設定為0,由於它小於10,Python進入while迴圈。進入迴圈後,以步長1的方式往上數。因此current_number為1。接下來,if語句檢查current_number與2的求模運算結果。如果結果為0(意味著current_number可被2整除),就執行continue語句,讓Python忽略餘下的程式碼,並返回迴圈的開頭。如果當前的數不能被2整除,就執行迴圈中餘下的程式碼,將這個數打印出來:

6. 避免無限迴圈

每個while迴圈都必須有停止執行的途徑,這樣才不會沒完沒了地執行下去。例如,下面的迴圈從1數到5:

但如果像下面這樣不小心遺漏了程式碼行x += 1,這個迴圈將沒完沒了地執行:

在這裡,x的初始值為1,但根本不會變。因此條件測試x <= 5始終為True,導致while迴圈沒完沒了地列印1。
每個程式設計師都會偶爾因不小心而編寫出無限迴圈,在迴圈的退出條件比較微妙時尤其如此。如果程式陷入無限迴圈。可按Ctrl + C,也可關閉顯示程式輸出的終端視窗。
要避免編寫無限迴圈,務必對每個while迴圈進行測試,確保其按預期那樣結束。如果你希望程式在使用者輸入特定值時結束,可執行程式並輸入這樣的值。如果在這種情況下程式沒有結果,請檢查程式處理這個值的方式,確認程式至少有一個這樣的地方能讓迴圈條件為False,或者讓break語句得以執行。
注意:Sublime Text等一些編輯器內嵌了輸出視窗,這可能導致難以結束無限迴圈,不得不通過關閉編輯器來結束。在這種情況下,可在輸出視窗中單擊滑鼠,再按Ctrl + C,這樣應該能夠結束無限迴圈。

三、使用while迴圈處理列表和字典

到目前為止,我們每次都只處理了一項童虎資訊:獲取使用者的輸入,再將輸入打印出來或作出應答:迴圈再次執行時,獲悉另一個輸入值並做出響應。然而,要記錄大量的使用者和資訊,需要在while迴圈中使用列表和字典。
for迴圈是一種遍歷列表的有效方式,但不應在for迴圈中修改列表,否則將導致Python難以跟蹤其中的元素。要在遍歷列表的同時對其進行修改,可使用while迴圈。通過將while迴圈同列表和字典結合起來使用,可收集、儲存並組織大量輸入,供以後檢視和顯示。

1. 在列表之間移動元素

假設有一個列表包含新註冊但還未驗證的網站使用者。驗證這些使用者後,如何將他們移到另一個已驗證使用者列表中呢?一種辦法是使用一個while迴圈,在驗證使用者的同時將其從未驗證使用者列表中提取出來,再將其加入另一個已驗證使用者列表中。程式碼可能類似於下面這樣:

首先建立一個未驗證使用者列表。其中包含使用者zhangsan、lisi和wangwu,還建立了一個空列表。用於儲存已驗證的使用者。然後while迴圈將不斷執行,直到列表unconfirmed_users變成空的。在此迴圈中,方法pop()以每次一個的方式從列表unconfirmed_users末尾刪除未驗證的使用者。由於wangwu位於列表unconfirmed末尾,其名字將首先被刪除、賦給變數current_user並加入列表confirmed_users中。接下來是lisi,然後是zhangsan。
為模擬使用者驗證過程,我們列印一條驗證並將使用者加入已驗證使用者列表中。未驗證使用者列表越來越短,而已驗證使用者列表越來越長。為驗證使用者列表為空後結束迴圈,再列印已驗證使用者列表:

2. 刪除為特定值的所有列表元素

之前,我們使用函式remove()來刪除列表中的特定值。這之所以可行,是因為要刪除的值只在列表中出現一次。如果要刪除列表中所有為特定值的元素,該怎麼辦呢?
假設你有一個寵物列表,其中包含多個值為'cat'的元素。要刪除所有這些元素,可不斷執行一個while迴圈,知道列表中不再包含值'cat',如下所示:

首先建立一個列表,其中包含多個值為'cat'的元素。列印這個列表後,Python進入while迴圈,因為它發現'cat'在列表中至少出現了一次。進入該迴圈後,Python刪除第一個'cat'並返回到while程式碼行,然後發現第二個'cat'還包含在列表中,因此再次進入迴圈。它不斷刪除'cat',知道這個值不再包含在列表中,然後退出迴圈並再次列印列表:

3. 使用使用者輸入來填充字典

可使用while迴圈提示使用者輸入任意多的資訊。下面建立一個調查程式,其中的迴圈每次執行時都提示輸入被調查者的名字和回答。我們將手機的資料儲存在一個字典中,以便將回答同被調查者關聯起來:

這個程式首先定義了一個空字典(responses),並設定了一個標誌(polling_active)用於指出調查是否繼續。只要polling_active為True,Python就執行whilr迴圈中的程式碼。
在這個迴圈中,提示使用者輸入其名字及其喜歡爬哪座山。將這些資訊儲存在字典reponses中,然後詢問使用者是否繼續調查。如果使用者輸入yes,程式將再次進入while迴圈;如果使用者輸入no,標誌polling_active將被設定為False,而while迴圈將就此結束。最後一個程式碼塊顯示調查結果。
如果執行這個程式,並輸入一些名字和回答,輸出將類似於下面這樣: