第 5 章 if 語句
程式設計時經常需要檢查一系列條件,並據此決定採取什麼措施。在Python中,if 語句讓你能夠檢查程式的當前狀態,並據此採取相應的措施。
在本章中,你將學習條件測試,以檢查感興趣的任何條件。你將學習簡單的if 語句,以及創建一系列複雜的if 語句來確定當前到底處於什麼情形。接下來,你將把學到的知識應用於列表,以編寫for 迴圈,以一種方式處理清單中的大多數元素,並以另一種不同的方式處理包含特定值的元素。
5.1 一個簡單示例
下面是一個簡短的示例,演示了如何使用if 語句來正確地處理特殊情形。假設你有一個汽車列表,並想將其中每輛汽車的名稱列印出來。對於大多數汽車,都應以首字母大寫的方式列印其名稱,但對於汽車名'bmw' ,應以全大寫的方式列印。下面的代碼遍歷一個清單,並以首字母大寫的方式列印其中的汽車名,但對於汽車名'bmw' ,以全大寫的方式列印:
cars.py
cars = ['audi', 'bmw', 'subaru', 'toyota']
for car in cars:
❶ if car == 'bmw':
print(car.upper())
else:
print(car.title())
這個示例中的迴圈首先檢查當前的汽車名是否是'bmw' (見❶)。如果是,就以全大寫的方式列印它;否則就以首字母大寫的方式列印:
Audi
BMW
Subaru
Toyota
這個示例涵蓋了本章將介紹的很多概念。下面先來介紹可用來在程式中檢查條件的測試。
5.2 條件測試
每條if 語句的核心都是一個值為True 或False 的運算式,這種運算式被稱為條件測試 。Python根據條件測試的值為True 還是False 來決定是否執行if 語句中的代碼。如果條件測試的值為True ,Python就執行緊跟在if 語句後面的代碼;如果為False ,Python就忽略這些代碼。
5.2.1 檢查是否相等
大多數條件測試都將一個變數的當前值同特定值進行比較。最簡單的條件測試檢查變數的值是否與特定值相等:
❶ >>> car = 'bmw'
❷ >>> car == 'bmw'
True
我們首先使用一個等號將car 的值設置為'bmw' (見❶),這種做法你已見過很多次。接下來,使用兩個等號(== )檢查car 的值是否為'bmw' 。這個相等運算子 在它兩邊的值相等時返回True ,否則返回False 。在這個示例中,兩邊的值相等,因此Python返回True 。
如果變數car 的值不是'bmw' ,上述測試將返回False :
❶ >>> car = 'audi'
❷ >>> car == 'bmw'
False
一個等號是陳述;對於❶處的代碼,可解讀為“將變數car 的值設置為'audi' ”。兩個等號是發問;對於❷處的代碼,可解讀為“變數car 的值是'bmw' 嗎?”。大多數程式設計語言使用等號的方式都與這裡演示的相同。
5.2.2 檢查是否相等時不考慮大小寫
在Python中檢查是否相等時區分大小寫,例如,兩個大小寫不同的值會被視為不相等:
>>> car = 'Audi'
>>> car == 'audi'
False
如果大小寫很重要,這種行為有其優點。但如果大小寫無關緊要,而只想檢查變數的值,可將變數的值轉換為小寫,再進行比較:
>>> car = 'Audi'
>>> car.lower() == 'audi'
True
無論值'Audi' 的大小寫如何,上述測試都將返回True ,因為該測試不區分大小寫。函數lower() 不會修改存儲在變數car 中的值,因此進行這樣的比較時不會影響原來的變數:
❸ >>> car = 'Audi'
❷ >>> car.lower() == 'audi'
True
❸ >>> car
'Audi'
在❶處,我們將首字母大寫的字串'Audi' 存儲在變數car 中;在❷處,我們獲取變數car 的值並將其轉換為小寫,再將結果與字串'audi' 進行比較。這兩個字串相同,因此Python返回True 。從❸處的輸出可知,這個條件測試並沒有影響存儲在變數car 中的值。
網站採用類似的方式讓使用者輸入的資料符合特定的格式。例如,網站可能使用類似的測試來確保用戶名是獨一無二的,而並非只是與另一個用戶名的大小寫不同。用戶提交新的用戶名時,將把它轉換為小寫,並與所有既有用戶名的小寫版本進行比較。執行這種檢查時,如果已經有用戶名'john' (不管大小寫如何),則用戶提交用戶名'John' 時將遭到拒絕。
5.2.3 檢查是否不相等
要判斷兩個值是否不等,可結合使用驚嘆號和等號(!= ),其中的驚嘆號表示不 ,在很多程式設計語言中都如此。
下面再使用一條if 語句來演示如何使用不等運算子。我們將把要求的比薩配料存儲在一個變數中,再列印一條消息,指出顧客要求的配料是否是意式小銀魚(anchovies):
toppings.py
requested_topping = 'mushrooms'
❶ if requested_topping != 'anchovies':
print("Hold the anchovies!")
❶處的代碼行將requested_topping 的值與'anchovies' 進行比較,如果它們不相等,Python將返回True ,進而執行緊跟在if 語句後面的代碼;如果這兩個值相等,Python將返回False ,因此不執行緊跟在if 語句後面的代碼。
由於requested_topping 的值不是'anchovies' ,因此執行print 語句:
Hold the anchovies!
你編寫的大多數條件運算式都檢查兩個值是否相等,但有時候檢查兩個值是否不等的效率更高。
5.2.4 比較數字
檢查數值非常簡單,例如,下面的代碼檢查一個人是否是18歲:
>>> age = 18
>>> age == 18
True
你還可以檢查兩個數位是否不等,例如,下面的代碼在提供的答案不正確時列印一條消息:
magic_number.py
answer = 17
❶ if answer != 42:
print("That is not the correct answer. Please try again!")
answer (17 )不是42 ,❶處的條件得到滿足,因此縮進的代碼塊得以執行:
That is not the correct answer. Please try again!
條件陳述式中可包含各種數學比較,如小於、小於等於、大於、大於等於:
>>> age = 19
>>> age < 21
True
>>> age <= 21
True
>>> age > 21
False
>>> age >= 21
False
在if 語句中可使用各種數學比較,這讓你能夠直接檢查關心的條件。
5.2.5 檢查多個條件
你可能想同時檢查多個條件,例如,有時候你需要在兩個條件都為True 時才執行相應的操作,而有時候你只要求一個條件為True 時就執行相應的操作。在這些情況下,關鍵字and 和or 可助你一臂之力。
1. 使用and 檢查多個條件
要檢查是否兩個條件都為True ,可使用關鍵字and 將兩個條件測試合而為一;如果每個測試都通過了,整個運算式就為True ;如果至少有一個測試沒有通過,整個運算式就為False 。
例如,要檢查是否兩個人都不小於21歲,可使用下面的測試:
❶ >>> age_0 = 22
>>> age_1 = 18
❷ >>> age_0 >= 21 and age_1 >= 21
False
❸ >>> age_1 = 22
>>> age_0 >= 21 and age_1 >= 21
True
在❶處,我們定義了兩個用於存儲年齡的變數:age_0 和age_1 。在❷處,我們檢查這兩個變數是否都大於或等於21;左邊的測試通過了,但右邊的測試沒有通過,因此整個條件運算式的結果為False 。在❸處,我們將age_1 改為22,這樣age_1 的值大於21,因此兩個測試都通過了,導致整個條件運算式的結果為True 。
為改善可讀性,可將每個測試都分別放在一對括弧內,但並非必須這樣做。如果你使用括弧,測試將類似於下面這樣:
(age_0 >= 21) and (age_1 >= 21)
2. 使用or 檢查多個條件
關鍵字or 也能夠讓你檢查多個條件,但只要至少有一個條件滿足,就能通過整個測試。僅當兩個測試都沒有通過時,使用or 的運算式才為False 。
下面再次檢查兩個人的年齡,但檢查的條件是至少有一個人的年齡不小於21歲:
❶ >>> age_0 = 22
>>> age_1 = 18
❷ >>> age_0 >= 21 or age_1 >= 21
True
❶ >>> age_0 = 18
>>> age_0 >= 21 or age_1 >= 21
False
同樣,我們首先定義了兩個用於存儲年齡的變數(見❶)。由於❷處對age_0 的測試通過了,因此整個運算式的結果為True 。接下來,我們將age_0 減小為18;在❸處的測試中,兩個測試都沒有通過,因此整個運算式的結果為False 。
5.2.6 檢查特定值是否包含在列表中
有時候,執行操作前必須檢查列表是否包含特定的值。例如,結束使用者的註冊過程前,可能需要檢查他提供的用戶名是否已包含在用戶名列表中。在地圖程式中,可能需要檢查使用者提交的位置是否包含在已知位置列表中。
要判斷特定的值是否已包含在列表中,可使用關鍵字in 。來看你可能為比薩店編寫的一些代碼;這些代碼首先創建一個列表,其中包含用戶點的比薩配料,然後檢查特定的配料是否包含在該列表中。
>>> requested_toppings = ['mushrooms', 'onions', 'pineapple']
❶ >>> 'mushrooms' in requested_toppings
True
❷ >>> 'pepperoni' in requested_toppings
False
在❶處和❷處,關鍵字in 讓Python檢查列表requested_toppings 是否包含'mushrooms' 和'pepperoni' 。這種技術很有用,它讓你能夠在創建一個列表後,輕鬆地檢查其中是否包含特定的值。
5.2.7 檢查特定值是否不包含在列表中
還有些時候,確定特定的值未包含在列表中很重要;在這種情況下,可使用關鍵字not in 。例如,如果有一個列表,其中包含被禁止在論壇上發表評論的用戶,就可在允許用戶提交評論前檢查他是否被禁言:
banned_users.py
banned_users = ['andrew', 'carolina', 'david']
user = 'marie'
❶ if user not in banned_users:
print(user.title() + ", you can post a response if you wish.")
❶處的代碼行明白易懂:如果user 的值未包含在列表banned_users 中,Python將返回True ,進而執行縮進的代碼行。
用戶'marie' 未包含在列表banned_users 中,因此她將看到一條邀請她發表評論的消息:
Marie, you can post a response if you wish.
5.2.8 布林運算式
隨著你對程式設計的瞭解越來越深入,將遇到術語布林運算式 ,它不過是條件測試的別名。與條件運算式一樣,布林運算式的結果要麼為True ,要麼為False 。
布林值通常用於記錄條件,如遊戲是否正在運行,或用戶是否可以編輯網站的特定內容:
game_active = True
can_edit = False
在跟蹤程式狀態或程式中重要的條件方面,布林值提供了一種高效的方式。
動手試一試
5-1 條件測試 :編寫一系列條件測試;將每個測試以及你對其結果的預測和實際結果都列印出來。你編寫的代碼應類似於下面這樣:
car = 'subaru'
print("Is car == 'subaru'? I predict True.")
print(car == 'subaru')
print("\nIs car == 'audi'? I predict False.")
print(car == 'audi')
· 詳細研究實際結果,直到你明白了它為何為True 或False 。
· 創建至少10個測試,且其中結果分別為True 和False 的測試都至少有5個。
5-2 更多的條件測試 :你並非只能創建10個測試。如果你想嘗試做更多的比較,可再編寫一些測試,並將它們加入到conditional_tests.py中。對於下面列出的各種測試,至少編寫一個結果為True 和False 的測試。
· 檢查兩個字串相等和不等。
· 使用函數lower() 的測試。
· 檢查兩個數字相等、不等、大於、小於、大於等於和小於等於。
· 使用關鍵字and 和or 的測試。
· 測試特定的值是否包含在列表中。
· 測試特定的值是否未包含在列表中。
5.3 if 語句
理解條件測試後,就可以開始編寫if 語句了。if 語句有很多種,選擇使用哪種取決於要測試的條件數。前面討論條件測試時,列舉了多個if 語句示例,下面更深入地討論這個主題。
5.3.1 簡單的if 語句
最簡單的if 語句只有一個測試和一個操作:
if conditional_test:
do something
在第1行中,可包含任何條件測試,而在緊跟在測試後面的縮進代碼塊中,可執行任何操作。如果條件測試的結果為True ,Python就會執行緊跟在if 語句後面的代碼;否則Python將忽略這些代碼。
假設有一個表示某人年齡的變數,而你想知道這個人是否夠投票的年齡,可使用如下代碼:
voting.py
age = 19
❶ if age >= 18:
❷ print("You are old enough to vote!")
在❶處,Python檢查變數age 的值是否大於或等於18;答案是肯定的,因此Python執行❷處縮進的print 語句:
You are old enough to vote!
在if 語句中,縮進的作用與for 迴圈中相同。如果測試通過了,將執行if 語句後面所有縮進的代碼行,否則將忽略它們。
在緊跟在if 語句後面的代碼塊中,可根據需要包含任意數量的代碼行。下面在一個人夠投票的年齡時再列印一行輸出,問他是否登記了:
age = 19
if age >= 18:
print("You are old enough to vote!")
print("Have you registered to vote yet?")
條件測試通過了,而兩條print 語句都縮進了,因此它們都將執行:
You are old enough to vote!
Have you registered to vote yet?
如果age 的值小於18,這個程式將不會有任何輸出。
5.3.2 if-else 語句
經常需要在條件測試通過了時執行一個操作,並在沒有通過時執行另一個操作;在這種情況下,可使用Python提供的if-else 語句。if-else 語句塊類似於簡單的if 語句,但其中的else 語句讓你能夠指定條件測試未通過時要執行的操作。
下面的代碼在一個人夠投票的年齡時顯示與前面相同的消息,同時在這個人不夠投票的年齡時也顯示一條消息:
age = 17
❶ if age >= 18:
print("You are old enough to vote!")
print("Have you registered to vote yet?")
❷ else:
print("Sorry, you are too young to vote.")
print("Please register to vote as soon as you turn 18!")
如果❶處的條件測試通過了,就執行第一個縮進的print 語句塊;如果測試結果為False ,就執行❷處的else 代碼塊。這次age 小於18,條件測試未通過,因此執行else 代碼塊中的代碼:
Sorry, you are too young to vote.
Please register to vote as soon as you turn 18!
上述代碼之所以可行,是因為只存在兩種情形:要麼夠投票的年齡,要麼不夠。if-else 結構非常適合用於要讓Python執行兩種操作之一的情形。在這種簡單的if-else 結構中,總是會執行兩個操作中的一個。
5.3.3 if-elif-else 結構
經常需要檢查超過兩個的情形,為此可使用Python提供的if-elif-else 結構。Python只執行if-elif-else 結構中的一個代碼塊,它依次檢查每個條件測試,直到遇到通過了的條件測試。測試通過後,Python將執行緊跟在它後面的代碼,並跳過餘下的測試。
在現實世界中,很多情況下需要考慮的情形都超過兩個。例如,來看一個根據年齡段收費的遊樂場:
· 4歲以下免費;
· 4~18歲收費5美元;
· 18歲(含)以上收費10美元。
如果只使用一條if 語句,如何確定門票價格呢?下面的代碼確定一個人所屬的年齡段,並列印一條包含門票價格的消息:
amusement_park.py
age = 12
❶ if age < 4:
print("Your admission cost is $0.")
❷ elif age < 18:
print("Your admission cost is $5.")
❸ else:
print("Your admission cost is $10.")
❶處的if 測試檢查一個人是否不滿4歲,如果是這樣,Python就列印一條合適的消息,並跳過餘下的測試。❷處的elif 代碼行其實是另一個if 測試,它僅在前面的測試未通過時才會運行。在這裡,我們知道這個人不小於4歲,因為第一個測試未通過。如果這個人未滿18歲,Python將列印相應的消息,並跳過else 代碼塊。如果if 測試和elif 測試都未通過,Python將運行❸處else 代碼塊中的代碼。
在這個示例中,❶處測試的結果為False ,因此不執行其代碼塊。然而,第二個測試的結果為True (12小於18),因此將執行其代碼塊。輸出為一個句子,向用戶指出了門票價格:
Your admission cost is $5.
只要年齡超過17歲,前兩個測試就都不能通過。在這種情況下,將執行else 代碼塊,指出門票價格為10美元。
為讓代碼更簡潔,可不在if-elif-else 代碼塊中列印門票價格,而只在其中設置門票價格,並在它後面添加一條簡單的print 語句:
age = 12
if age < 4:
❶ price = 0
elif age < 18:
❷ price = 5
else:
❸ price = 10
❹ print("Your admission cost is $" + str(price) + ".")
❶處、❷處和❸處的代碼行像前一個示例那樣,根據人的年齡設置變數price 的值。在if-elif-else 結構中設置price 的值後,一條未縮進的print 語句❹會根據這個變數的值列印一條消息,指出門票的價格。
這些代碼的輸出與前一個示例相同,但if-elif-else 結構的作用更小,它只確定門票價格,而不是在確定門票價格的同時列印一條消息。除效率更高外,這些修訂後的代碼還更容易修改:要調整輸出消息的內容,只需修改一條而不是三條print 語句。
5.3.4 使用多個elif 代碼塊
可根據需要使用任意數量的elif 代碼塊,例如,假設前述遊樂場要給老年人打折,可再添加一個條件測試,判斷顧客是否符合打折條件。下面假設對於65歲(含)以上的老人,可以半價(即5美元)購買門票:
age = 12
if age < 4:
price = 0
elif age < 18:
price = 5
❶ elif age < 65:
price = 10
❷ else:
price = 5
print("Your admission cost is $" + str(price) + ".")
這些代碼大都未變。第二個elif 代碼塊(見❶)通過檢查確定年齡不到65歲後,才將門票價格設置為全票價格——10美元。請注意,在else 代碼塊(見❷)中,必須將所賦的值改為5,因為僅當年齡超過65(含)時,才會執行這個代碼塊。
5.3.5 省略else 代碼塊
Python並不要求if-elif 結構後面必須有else 代碼塊。在有些情況下,else 代碼塊很有用;而在其他一些情況下,使用一條elif 語句來處理特定的情形更清晰:
age = 12
if age < 4:
price = 0
elif age < 18:
price = 5
elif age < 65:
price = 10
❶ elif age >= 65:
price = 5
print("Your admission cost is $" + str(price) + ".")
❶處的elif 代碼塊在顧客的年齡超過65(含)時,將價格設置為5美元,這比使用else 代碼塊更清晰些。經過這樣的修改後,每個代碼塊都僅在通過了相應的測試時才會執行。
else 是一條包羅萬象的語句,只要不滿足任何if 或elif 中的條件測試,其中的代碼就會執行,這可能會引入無效甚至惡意的資料。如果知道最終要測試的條件,應考慮使用一個elif 代碼塊來代替else 代碼塊。這樣,你就可以肯定,僅當滿足相應的條件時,你的代碼才會執行。
5.3.6 測試多個條件
if-elif-else 結構功能強大,但僅適合用於只有一個條件滿足的情況:遇到通過了的測試後,Python就跳過餘下的測試。這種行為很好,效率很高,讓你能夠測試一個特定的條件。
然而,有時候必須檢查你關心的所有條件。在這種情況下,應使用一系列不包含elif 和else 代碼塊的簡單if 語句。在可能有多個條件為True ,且你需要在每個條件為True 時都採取相應措施時,適合使用這種方法。
下麵再來看前面的比薩店示例。如果顧客點了兩種配料,就需要確保在其比薩中包含這些配料:
toppings.py
❶ requested_toppings = ['mushrooms', 'extra cheese']
❷ if 'mushrooms' in requested_toppings:
print("Adding mushrooms.")
❸ if 'pepperoni' in requested_toppings:
print("Adding pepperoni.")
❹ if 'extra cheese' in requested_toppings:
print("Adding extra cheese.")
print("\nFinished making your pizza!")
我們首先創建了一個列表,其中包含顧客點的配料(見❶)。❷處的if 語句檢查顧客是否點了配料蘑菇('mushrooms' ),如果點了,就列印一條確認消息。❸處檢查配料辣香腸('pepperoni' )的代碼也是一個簡單的if 語句,而不是elif 或else 語句;因此不管前一個測試是否通過,都將進行這個測試。❹處的代碼檢查顧客是否要求多加芝士('extra cheese' );不管前兩個測試的結果如何,都會執行這些代碼。每當這個程式運行時,都會進行這三個獨立的測試。
在這個示例中,會檢查每個條件,因此將在比薩中添加蘑菇並多加芝士:
Adding mushrooms.
Adding extra cheese.
Finished making your pizza!
如果像下面這樣轉而使用if-elif-else 結構,代碼將不能正確地運行,因為有一個測試通過後,就會跳過餘下的測試:
requested_toppings = ['mushrooms', 'extra cheese']
if 'mushrooms' in requested_toppings:
print("Adding mushrooms.")
elif 'pepperoni' in requested_toppings:
print("Adding pepperoni.")
elif 'extra cheese' in requested_toppings:
print("Adding extra cheese.")
print("\nFinished making your pizza!")
第一個測試檢查列表中是否包含'mushrooms' ,它通過了,因此將在比薩中添加蘑菇。然而,Python將跳過if-elif-else 結構中餘下的測試,不再檢查列表中是否包含'extra cheese' 和'pepperoni' 。其結果是,將添加顧客點的第一種配料,但不會添加其他的配料:
Adding mushrooms.
Finished making your pizza!
總之,如果你只想執行一個代碼塊,就使用if-elif-else 結構;如果要運行多個代碼塊,就使用一系列獨立的if 語句。
動手試一試
5-3 外星人顏色#1 :假設在遊戲中剛射殺了一個外星人,請創建一個名為alien_color 的變數,並將其設置為'green' 、'yellow' 或'red' 。
· 編寫一條if 語句,檢查外星人是否是綠色的;如果是,就列印一條消息,指出玩家獲得了5個點。
· 編寫這個程式的兩個版本,在一個版本中上述測試通過了,而在另一個版本中未通過(未通過測試時沒有輸出)。
alien_color = 'green'
if alien_color == 'green':
print("You just earned 5 points!")
輸出:
You just earned 5 points!
不能通過測試的版本:
alien_color = 'red'
if alien_color == 'green':
print("You just earned 5 points!")
(沒有輸出)
5-4 外星人顏色#2 :像練習5-3那樣設置外星人的顏色,並編寫一個if-else 結構。
· 如果外星人是綠色的,就列印一條消息,指出玩家因射殺該外星人獲得了5個點。
· 如果外星人不是綠色的,就列印一條消息,指出玩家獲得了10個點。
· 編寫這個程式的兩個版本,在一個版本中執行if 代碼塊,而在另一個版本中執行else 代碼塊。
執行if代碼塊的版本:
alien_color = 'green'
if alien_color == 'green':
print("You just earned 5 points!")
else:
print("You just earned 10 points!")
輸出:
You just earned 5 points!
執行else代碼塊的版本:
alien_color = 'yellow'
if alien_color == 'green':
print("You just earned 5 points!")
else:
print("You just earned 10 points!")
輸出:
You just earned 10 points!
5-5 外星人顏色#3 :將練習5-4中的if-else 結構改為if-elif-else 結構。
· 如果外星人是綠色的,就列印一條消息,指出玩家獲得了5個點。
· 如果外星人是黃色的,就列印一條消息,指出玩家獲得了10個點。
· 如果外星人是紅色的,就列印一條消息,指出玩家獲得了15個點。
· 編寫這個程式的三個版本,它們分別在外星人為綠色、黃色和紅色時列印一條消息。
外星人為紅色的版本:
alien_color = 'red'
if alien_color == 'green':
print("You just earned 5 points!")
elif alien_color == 'yellow':
print("You just earned 10 points!")
else:
print("You just earned 15 points!")
輸出:
You just earned 15 points!
5-6 人生的不同階段 :設置變數age 的值,再編寫一個if-elif-else 結構,根據age 的值判斷處於人生的哪個階段。
· 如果一個人的年齡小於2歲,就列印一條消息,指出他是嬰兒。
· 如果一個人的年齡為2(含)~4歲,就列印一條消息,指出他正蹣跚學步。
· 如果一個人的年齡為4(含)~13歲,就列印一條消息,指出他是兒童。
· 如果一個人的年齡為13(含)~20歲,就列印一條消息,指出他是青少年。
· 如果一個人的年齡為20(含)~65歲,就列印一條消息,指出他是成年人。
· 如果一個人的年齡超過65(含)歲,就列印一條消息,指出他是老年人。
age = 17
if age < 2:
print("You're a baby!")
elif age < 4:
print("You're a toddler!")
elif age < 13:
print("You're a kid!")
elif age < 20:
print("You're a teenager!")
elif age < 65:
print("You're an adult!")
else:
print("You're an elder!")
輸出:
You're a teenager!
5-7 喜歡的水果 :創建一個列表,其中包含你喜歡的水果,再編寫一系列獨立的if 語句,檢查列表中是否包含特定的水果。
· 將該列表命名為favorite_fruits ,並在其中包含三種水果。
· 編寫5條if 語句,每條都檢查某種水果是否包含在列表中,如果包含在列表中,就列印一條消息,如“You really like bananas!”。
favorite_fruits = ['blueberries', 'salmonberries', 'peaches']
if 'bananas' in favorite_fruits:
print("You really like bananas!")
if 'apples' in favorite_fruits:
print("You really like apples!")
if 'blueberries' in favorite_fruits:
print("You really like blueberries!")
if 'kiwis' in favorite_fruits:
print("You really like kiwis!")
if 'peaches' in favorite_fruits:
print("You really like peaches!")
輸出:
You really like blueberries!
You really like peaches!
5.4 使用if 語句處理列表
通過結合使用if 語句和列表,可完成一些有趣的任務:對列表中特定的值做特殊處理;高效地管理不斷變化的情形,如餐館是否還有特定的食材;證明代碼在各種情形下都將按預期那樣運行。
5.4.1 檢查特殊元素
本章開頭通過一個簡單示例演示了如何處理特殊值'bmw' ——它需要採用不同的格式進行列印。既然你對條件測試和if 語句有了大致的認識,下面來進一步研究如何檢查列表中的特殊值,並對其做合適的處理。
繼續使用前面的比薩店示例。這家比薩店在製作比薩時,每添加一種配料都列印一條消息。通過創建一個列表,在其中包含顧客點的配料,並使用一個迴圈來指出添加到比薩中的配料,可以以極高的效率編寫這樣的代碼:
toppings.py
requested_toppings = ['mushrooms', 'green peppers', 'extra cheese']
for requested_topping in requested_toppings:
print("Adding " + requested_topping + ".")
print("\nFinished making your pizza!")
輸出很簡單,因為上述代碼不過是一個簡單的for 迴圈:
Adding mushrooms.
Adding green peppers.
Adding extra cheese.
Finished making your pizza!
然而,如果比薩店的青椒用完了,該如何處理呢?為妥善地處理這種情況,可在for 迴圈中包含一條if 語句:
requested_toppings = ['mushrooms', 'green peppers', 'extra cheese']
for requested_topping in requested_toppings:
❶ if requested_topping == 'green peppers':
print("Sorry, we are out of green peppers right now.")
❷ else:
print("Adding " + requested_topping + ".")
print("\nFinished making your pizza!")
這裡在比薩中添加每種配料前都進行檢查。❶處的代碼檢查顧客點的是否是青椒,如果是,就顯示一條消息,指出不能點青椒的原因。❷處的else 代碼塊確保其他配料都將添加到比薩中。
輸出表明,妥善地處理了顧客點的每種配料:
Adding mushrooms.
Sorry, we are out of green peppers right now.
Adding extra cheese.
Finished making your pizza!
5.4.2 確定列表不是空的
到目前為止,對於處理的每個列表都做了一個簡單的假設,即假設它們都至少包含一個元素。我們馬上就要讓使用者來提供存儲在清單中的資訊,因此不能再假設迴圈運行時列表不是空的。有鑑於此,在運行for 迴圈前確定列表是否為空很重要。
下面在製作比薩前檢查顧客點的配料列表是否為空。如果列表是空的,就向顧客確認他是否要點普通比薩;如果列表不為空,就像前面的示例那樣製作比薩:
❶ requested_toppings = []
❷ if requested_toppings:
for requested_topping in requested_toppings:
print("Adding " + requested_topping + ".")
print("\nFinished making your pizza!")
❸ else:
print("Are you sure you want a plain pizza?")
在這裡,我們首先創建了一個空列表,其中不包含任何配料(見❶)。在❷處我們進行了簡單檢查,而不是直接執行for 迴圈。在if 語句中將列表名用在條件運算式中時,Python將在清單至少包含一個元素時返回True ,並在列表為空時返回False 。如果requested_toppings 不為空,就運行與前一個示例相同的for 迴圈;否則,就列印一條消息,詢問顧客是否確實要點不加任何配料的普通比薩(見❸)。
在這裡,這個列表為空,因此輸出如下——詢問顧客是否確實要點普通比薩:
Are you sure you want a plain pizza?
如果這個清單不為空,將顯示在比薩中添加的各種配料的輸出。
5.4.3 使用多個列表
顧客的要求往往五花八門,在比薩配料方面尤其如此。如果顧客要在比薩中添加炸薯條,該怎麼辦呢?可使用列表和if 語句來確定能否滿足顧客的要求。
來看看在製作比薩前如何拒絕怪異的配料要求。下面的示例定義了兩個列表,其中第一個列表包含比薩店供應的配料,而第二個列表包含顧客點的配料。這次對於requested_toppings 中的每個元素,都檢查它是否是比薩店供應的配料,再決定是否在比薩中添加它:
❶ available_toppings = ['mushrooms', 'olives', 'green peppers',
'pepperoni', 'pineapple', 'extra cheese']
❷ requested_toppings = ['mushrooms', 'french fries', 'extra cheese']
❸ for requested_topping in requested_toppings:
❹ if requested_topping in available_toppings:
print("Adding " + requested_topping + ".")
❺ else:
print("Sorry, we don't have " + requested_topping + ".")
print("\nFinished making your pizza!")
在❶處,我們定義了一個列表,其中包含比薩店供應的配料。請注意,如果比薩店供應的配料是固定的,也可使用一個元組來存儲它們。在❷處,我們又創建了一個列表,其中包含顧客點的配料,請注意那個不同尋常的配料——'french fries' 。在❸處,我們遍歷顧客點的配料列表。在這個迴圈中,對於顧客點的每種配料,我們都檢查它是否包含在供應的配料列表中(見❹);如果答案是肯定的,就將其加入到比薩中,否則將運行else 代碼塊(見❺):列印一條消息,告訴顧客不供應這種配料。
這些代碼的輸出整潔而詳實:
Adding mushrooms.
Sorry, we don't have french fries.
Adding extra cheese.
Finished making your pizza!
通過為數不多的幾行代碼,我們高效地處理了一種真實的情形!
動手試一試
5-8 以特殊方式跟管理員打招呼 :創建一個至少包含5個用戶名的列表,且其中一個用戶名為'admin' 。想像你要編寫代碼,在每位用戶登錄網站後都列印一條問候消息。遍歷用戶名列表,並向每位使用者列印一條問候消息。
· 如果用戶名為'admin' ,就列印一條特殊的問候消息,如“Hello admin, would you like to see a status report?”。
· 否則,列印一條普通的問候消息,如“Hello Eric, thank you for logging in again”。
usernames = ['eric', 'willie', 'admin', 'erin', 'ever']
for username in usernames:
if username == 'admin':
print("Hello admin, would you like to see a status
report?")
else:
print("Hello " + username + ", thank you for logging in again!")
輸出:
Hello eric, thank you for logging in again!
Hello willie, thank you for logging in again!
Hello admin, would you like to see a status report?
Hello erin, thank you for logging in again!
Hello ever, thank you for logging in again!
5-9 處理沒有用戶的情形 :在為完成練習5-8編寫的程式中,添加一條if 語句,檢查用戶名列表是否為空。
· 如果為空,就列印消息“We need to find some users!”。
· 刪除列表中的所有用戶名,確定將列印正確的消息。
usernames = []
if usernames:
for username in usernames:
if username == 'admin':
print("Hello admin, would you like to see a status
report?")
else:
print("Hello " + username + ", thank you for logging in again!")
else:
print("We need to find some users!")
輸出:
We need to find some users!
5-10 檢查用戶名 :按下面的說明編寫一個程式,類比網站確保每位用戶的用戶名都獨一無二的方式。
· 創建一個至少包含5個用戶名的列表,並將其命名為current_users 。
· 再創建一個包含5個用戶名的列表,將其命名為new_users ,並確保其中有一兩個用戶名也包含在列表current_users 中。
· 遍歷列表new_users ,對於其中的每個用戶名,都檢查它是否已被使用。如果是這樣,就列印一條消息,指出需要輸入別的用戶名;否則,列印一條消息,指出這個用戶名未被使用。
· 確保比較時不區分大消息;換句話說,如果用戶名'John' 已被使用,應拒絕用戶名'JOHN' 。
current_users = ['eric', 'willie', 'admin', 'erin', 'Ever']
new_users = ['sarah', 'Willie', 'PHIL', 'ever', 'Iona']
current_users_lower = [user.lower() for user in current_users]
for new_user in new_users:
if new_user.lower() in current_users_lower:
print("Sorry " + new_user + ", that name is taken.")
else:
print("Great, " + new_user + " is still available.")
輸出:
Great, sarah is still available.
Sorry Willie, that name is taken.
Great, PHIL is still available.
Sorry ever, that name is taken.
Great, Iona is still available.
注意:如果你還不熟悉列表解析,可像下面這樣使用迴圈來生成列表current_users_lower:
current_users_lower = []
for user in current_users:
current_users_lower.append(user.lower())
5-11 序數 :序數表示位置,如1st和2nd。大多數序數都以th結尾,只有1、2和3例外。
· 在一個清單中存儲數位1~9。
· 遍歷這個列表。
· 在迴圈中使用一個if-elif-else 結構,以列印每個數位對應的序數。輸出內容應為1st 、2nd 、3rd 、4th 、5th 、6th 、7th 、8th 和9th ,但每個序數都獨佔一行。
numbers = list(range(1,10))
for number in numbers:
if number == 1:
print("1st")
elif number == 2:
print("2nd")
elif number == 3:
print("3rd")
else:
print(str(number) + "th")
輸出:
1st
2nd
3rd
4th
5th
6th
7th
8th
9th
5.5 設置if 語句的格式
本章的每個示例都展示了良好的格式設置習慣。在條件測試的格式設置方面,PEP 8提供的唯一建議是,在諸如== 、>= 和<= 等比較運算子兩邊各添加一個空格,例如,if age < 4: 要比if age<4: 好。
這樣的空格不會影響Python對代碼的解讀,而只是讓代碼閱讀起來更容易。
動手試一試
5-12 設置if 語句的格式 :審核你在本章編寫的程式,確保正確地設置了條件測試的格式。
5-13 自己的想法 :與剛拿起本書時相比,現在你是一名能力更強的程式師了。鑒於你對如何在程式中類比現實情形有了更深入的認識,你可以考慮使用程式來解決一些問題。隨著程式設計技能不斷提高,你可能想解決一些問題,請將這方面的想法記錄下來。想想你可能想編寫的遊戲、想研究的資料集以及想創建的Web應用程式。
5.6 小結
在本章中,你學習了如何編寫結果要麼為Ture 要麼為False 的條件測試。你學習了如何編寫簡單的if 語句、if-else 語句和if-elif-else 結構。在程式中,你使用了這些結構來測試特定的條件,以確定這些條件是否滿足。你學習了如何在利用高效的for 迴圈的同時,以不同於其他元素的方式對特定的清單元素進行處理。你還再次學習了Python就代碼格式方面提出的建議,這可確保即便你編寫的程式越來越複雜,其代碼依然易於閱讀和理解。
在第6章,你將學習Python字典。字典類似於清單,但讓你能夠將不同的資訊關聯起來。你將學習如何創建和遍歷字典,以及如何將字典同清單和if 語句結合起來使用。學習字典讓你能夠類比更多現實世界的情形。

0 留言:
發佈留言