Python條件語(yǔ)句詳解:if、else、switch都有了
01 if條件語(yǔ)句
if語(yǔ)句用于檢測(cè)某個(gè)條件是否成立。如果成立,則執(zhí)行if語(yǔ)句內(nèi)的程序;否則,跳過(guò)if語(yǔ)句,執(zhí)行后面的內(nèi)容。if語(yǔ)句的格式如下。
- if(表達(dá)式):
- 語(yǔ)句1
- else:
- 語(yǔ)句2
if語(yǔ)句的執(zhí)行過(guò)程如下:如果表達(dá)式的布爾值為真,則執(zhí)行語(yǔ)句1;否則,執(zhí)行語(yǔ)句2。其中的else子句可以省略,表達(dá)式兩側(cè)的括號(hào)也可以省略。
在講解if語(yǔ)句之前,先介紹一下Python中的控制臺(tái)輸入函數(shù)。在C語(yǔ)言中,使用scanf()和getchar()捕獲用戶(hù)輸入,而Java語(yǔ)言的System.in包提供了控制臺(tái)輸入的方法。Python也提供了類(lèi)似功能的函數(shù)——input(),用于捕獲用戶(hù)的原始輸入并將其轉(zhuǎn)為字符串。input()函數(shù)的聲明如下。
- input([prompt]) -> string
參數(shù)prompt是控制臺(tái)中對(duì)于輸入的提示文字,提示用戶(hù)輸入,返回值為字符串。如果輸入的是數(shù)字,返回的還是字符串,那么使用前需要調(diào)用int()做一下字符串和數(shù)字類(lèi)型的轉(zhuǎn)換。下面這段代碼說(shuō)明了字符串和數(shù)字類(lèi)型的轉(zhuǎn)換。
- x = input("x:")
- x = int(x)
- x = x + 1
如果不調(diào)用int()把字符串轉(zhuǎn)換為數(shù)字,而直接計(jì)算表達(dá)式x = x + 1,將提示如下錯(cuò)誤。
- TypeError: Can't convert 'int' object to str implicitly
下面這段代碼演示了if語(yǔ)句的執(zhí)行流程。
- 1# 執(zhí)行if語(yǔ)句內(nèi)的程序
- 2a = input("a:")
- 3a = int(a)
- 4b = input("b:")
- 5b = int(b)
- 6if(a > b):
- 7 print (a, " > ", b)
【代碼說(shuō)明】
- 第2行代碼定義了變量a。
- 第3行將用戶(hù)輸入的a轉(zhuǎn)換為int類(lèi)型。
- 第4行代碼定義了變量b。
- 第5行將用戶(hù)輸入的b轉(zhuǎn)換為int類(lèi)型。
- 第6行代碼判斷變量a、b的大小。
- 對(duì)于第7行代碼,假設(shè)a=2、b=1,輸出結(jié)果:2>1。
如果不滿(mǎn)足if語(yǔ)句內(nèi)的條件,程序?qū)⑻^(guò)if語(yǔ)句,執(zhí)行后面的內(nèi)容。
- 1# 跳過(guò)if語(yǔ)句
- 2a = input("a:")
- 3a = int(a)
- 4b = input("b:")
- 5b = int(b)
- 6if(a > b):
- 7 print (a, " > ", b)
- 8print (a, " < ", b)
【代碼說(shuō)明】
- 假設(shè)a=1、b=2,第6行代碼中變量a的值小于變量b的值,因此,程序跳轉(zhuǎn)執(zhí)行第8行代碼。
- 第8行代碼輸出結(jié)果:1<2。
【例3-1】把上面的代碼改寫(xiě)成if… else…結(jié)構(gòu)。
【例3-1.py】
- 1# if… else…語(yǔ)句
- 2a = input("a:")
- 3a = int(a)
- 4b = input("b:")
- 5b = int(b)
- 6if(a > b):
- 7 print (a, " > ", b)
- 8else:
- 9 print (a, " < ", b)
【代碼說(shuō)明】
- 假設(shè)a=1、b=2,第6行代碼中變量a的值小于變量b的值。因此,程序跳轉(zhuǎn)到else子句。
- 第9行代碼輸出結(jié)果:1<2。
注意:else子句后需要加一個(gè)冒號(hào),使Python解釋器能識(shí)別出else子句對(duì)應(yīng)的代碼塊。Java程序員可能會(huì)不習(xí)慣這種語(yǔ)法,往往會(huì)忽略else子句后的冒號(hào)。在Python 2中還可用raw_input()函數(shù)接收用戶(hù)輸入,其功能與Python 3的input()相同。而Python 2中的input()接收的值不轉(zhuǎn)換為字符串類(lèi)型,而是保留原始類(lèi)型,它在Python 3中已經(jīng)去除。
02 if…elif…else判斷語(yǔ)句
if…elif…else語(yǔ)句是對(duì)if…else…語(yǔ)句的補(bǔ)充。當(dāng)程序的條件分支很多時(shí),可以使用這種語(yǔ)句。if…elif…else語(yǔ)句相當(dāng)于C、Java中的if…elseif…else語(yǔ)句。該語(yǔ)句的格式如下。
- if(表達(dá)式1): 語(yǔ)句1
- elif(表達(dá)式2): 語(yǔ)句2
- …
- elif(表達(dá)式n): 語(yǔ)句n
- else: 語(yǔ)句m
if…elif…else語(yǔ)句的執(zhí)行過(guò)程:首先判斷表達(dá)式1的值是否為真。如果為真,則執(zhí)行語(yǔ)句1。否則,程序流轉(zhuǎn)到elif子句,判斷表達(dá)式2的值是否為真。如果表達(dá)式2的值為真,則執(zhí)行語(yǔ)句2。否則,程序進(jìn)入下面一個(gè)elif子句,以此類(lèi)推。如果所有的表達(dá)式都不成立,則程序執(zhí)行else子句的代碼。其中的else子句可以省略,表達(dá)式兩側(cè)的括號(hào)也可以省略。
下面【例3-2】中的這段代碼通過(guò)判斷學(xué)生的分?jǐn)?shù),確定學(xué)生成績(jī)的等級(jí)。
【例3-2.py】
- 1# if elif else語(yǔ)句
- 2score = float( input("score:")) # 接收用戶(hù)輸入并將其轉(zhuǎn)換為float類(lèi)型,當(dāng)輸入為小數(shù)時(shí),使用int轉(zhuǎn)換會(huì)報(bào)錯(cuò)
- 3if 90 <= score <= 100:
- 4 print("A")
- 5elif 80 <= score < 90:
- 6 print("B")
- 7elif 60 <= score < 80:
- 8 print("C")
- 9else:
- 0 print("D")
【代碼說(shuō)明】
- 第2行代碼定義了一個(gè)變量score,假設(shè)輸入的值為70。這個(gè)變量表示學(xué)生的分?jǐn)?shù)。接收用戶(hù)輸入并將其轉(zhuǎn)換為float類(lèi)型。
- 第3行代碼,分?jǐn)?shù)大于等于90并且小于等于100,則等級(jí)評(píng)定為“A”。
- 第5行代碼,分?jǐn)?shù)大于等于80并且小于90,則等級(jí)評(píng)定為“B”。
- 第7行代碼,分?jǐn)?shù)大于等于60并且小于80,則等級(jí)評(píng)定為“C”。此時(shí)條件表達(dá)式成立,程序流轉(zhuǎn)到第8行。輸出結(jié)果為C。
- 第9行代碼,當(dāng)前面的條件表達(dá)式都不成立時(shí),程序流轉(zhuǎn)到else子句。
03 if語(yǔ)句也可以嵌套
if語(yǔ)句的嵌套是指if語(yǔ)句中可以包含一個(gè)或多個(gè)if語(yǔ)句。嵌套的格式如下所示。
- if(表達(dá)式1):
- if(表達(dá)式2): 語(yǔ)句1
- elif(表達(dá)式3): 語(yǔ)句2
- …
- else: 語(yǔ)句3
- elif(表達(dá)式n):
- …
- else:
- …
下面【例3-3】中的這段代碼是一個(gè)嵌套的條件語(yǔ)句。如果x的值大于0,則y的值等于1;如果x的值等于0,則y的值等于0;如果x的值小于0,則y的值等于-1。
【例3-3.py】
- 1x = -1
- 2y = 99
- 3if(x >= 0):
- 4 if(x > 0):#嵌套的if語(yǔ)句
- 5 y = 1
- 6 else:
- 7 y = 0
- 8else:
- 9 y = -1
- 0print ("y =", y)
【代碼說(shuō)明】
- 第2行代碼定義了一個(gè)變量y。為了不和最終可能的輸出結(jié)果1、0、-1重復(fù),設(shè)置y的初始值為99。
- 第3行代碼判斷變量x的值。如果x大于等于0,則執(zhí)行下面嵌套的if語(yǔ)句。
- 第4行代碼,判讀x的值是否大于0。如果大于0,則執(zhí)行第5行代碼;否則,執(zhí)行第7行代碼。
- 第8行代碼,如果變量x的值小于0,則執(zhí)行第9行代碼。
- 第9行代碼,由于變量x的值為-1,因此y的值等于-1。
- 第10行代碼的輸出結(jié)果為-1。
嵌套語(yǔ)句可以組合出很多寫(xiě)法,但是要注意把所有的分支情況都考慮到。下面的這種寫(xiě)法是錯(cuò)誤的。
- 1# 錯(cuò)誤的嵌套語(yǔ)句
- 2x = -1
- 3y = 99
- 4if(x != 0): # 如果x不等于0
- 5 if(x > 0): #嵌套的if語(yǔ)句
- 6 y = 1
- 7else:
- 8 y = 0
- 9print ("y =", y)
【代碼說(shuō)明】
- 第4行代碼判斷變量x的值是否等于0。如果不等于0,則執(zhí)行if語(yǔ)句下面的代碼塊;否則執(zhí)行else子句的代碼。由于x的值等于-1,程序流轉(zhuǎn)到第5行。
- 第5行代碼判斷變量x的值是否大于0。如果大于0,則變量y的值設(shè)置為1。由于這里沒(méi)有考慮到變量x小于0的情況,所以程序直接跳轉(zhuǎn)到第9行。
- 第9行代碼,變量y的值并沒(méi)有被改變,程序的分支結(jié)構(gòu)沒(méi)有考慮到x小于0的情況,所以最終輸出的不是期望中的結(jié)果。輸出結(jié)果為99。
注意:編寫(xiě)條件語(yǔ)句時(shí),應(yīng)該盡可能避免使用嵌套語(yǔ)句。嵌套語(yǔ)句不便于閱讀,而且可能會(huì)忽略一些可能性。
04 switch語(yǔ)句的替代方案
switch語(yǔ)句用于編寫(xiě)多分支結(jié)構(gòu)的程序,類(lèi)似于if…elif…else語(yǔ)句。C語(yǔ)言中switch語(yǔ)句的結(jié)構(gòu)如下所示。
- switch(表達(dá)式) {
- case 常量表達(dá)式1: 語(yǔ)句1
- case 常量表達(dá)式2: 語(yǔ)句2
- …
- case 常量表達(dá)式n: 語(yǔ)句n
- default: 語(yǔ)句m
- }
switch語(yǔ)句表示的分支結(jié)構(gòu)比if…elif…else語(yǔ)句更清晰,代碼可讀性更高,但是Python并沒(méi)有提供switch語(yǔ)句,而是可以通過(guò)字典實(shí)現(xiàn)switch語(yǔ)句的功能。
實(shí)現(xiàn)方法分為兩步。首先,定義一個(gè)字典。字典是由鍵值對(duì)組成的集合。其次,調(diào)用字典的get()獲取相應(yīng)的表達(dá)式。
下面【例3-4】中的這段代碼通過(guò)算術(shù)運(yùn)算的符號(hào),獲取算術(shù)運(yùn)算表達(dá)式。
【例3-4.py】
- 1# 使用字典實(shí)現(xiàn)switch語(yǔ)句
- 2from __future__ import division# 導(dǎo)入division模塊
- 3x = 1
- 4y = 2
- 5operator = "/"
- 6result = { # 定義字典
- 7"+" : x + y,
- 8"-" : x - y,
- 9"*" : x * y,
- 10"/" : x / y
- 11}
- 12print (result.get(operator))
【代碼說(shuō)明】
- 第3、4行代碼定義了兩個(gè)操作數(shù)x、y。
- 第5行代碼定義了操作符變量operator,該變量用于存放算術(shù)運(yùn)算符。
- 第6行代碼定義了一個(gè)字典result。該字典的key值由“+”“-”“*”“/”四則運(yùn)算符組成。value值由對(duì)應(yīng)的算術(shù)表達(dá)式組成。
- 第12行代碼調(diào)用get()方法,get()的參數(shù)就是變量operator的值。由于operator的值為“/”,因此將執(zhí)行除法運(yùn)算。輸出結(jié)果為0.5。
另一種使用switch分支語(yǔ)句的方案是創(chuàng)建一個(gè)switch類(lèi),處理程序的流轉(zhuǎn)。這種實(shí)現(xiàn)方法比較復(fù)雜,涉及面向?qū)ο?、for循環(huán)、中斷語(yǔ)句、遍歷等知識(shí),實(shí)現(xiàn)步驟分為4步。
- 創(chuàng)建一個(gè)switch類(lèi),該類(lèi)繼承自Python的祖先類(lèi)object。調(diào)用構(gòu)造函數(shù)__init__()初始化需要匹配的字符串,并定義兩個(gè)成員變量value和fall。value用于存放需要匹配的字符串。fall用于記錄是否匹配成功,初始值為False,表示匹配不成功。如果匹配成功,程序向后執(zhí)行。
- 定義一個(gè)match()方法,該方法用于匹配case子句。這里需要考慮3種情況。首先是匹配成功的情況,其次是匹配失敗的默認(rèn)case子句,最后是case子句中沒(méi)有使用break中斷的情況。
- 重寫(xiě)__iter__()方法,定義了該方法后才能使switch類(lèi)用于循環(huán)語(yǔ)句中。__iter__()調(diào)用match()方法進(jìn)行匹配,通過(guò)yield關(guān)鍵字,使函數(shù)可以在循環(huán)中迭代。此外,調(diào)用異常StopIteration中斷循環(huán)。Python中的循環(huán)都是通過(guò)異常StopIteration中斷的。這樣switch類(lèi)就構(gòu)造完成了。
- 編寫(xiě)調(diào)用代碼,在for…in…循環(huán)中使用switch類(lèi)。
下面【例3-5】中的這段代碼實(shí)現(xiàn)了switch語(yǔ)句的功能。
【例3-5.py】
- 1class switch(object):# 定義switch類(lèi)
- 2 def __init__(self, value):# 初始化需要匹配的值value
- 3 self.value = value
- 4 self.fall = False # 如果匹配到的case語(yǔ)句中沒(méi)有break,則fall為True
- 5
- 6 def __iter__(self):# 定義__iter__()方法
- 7 yield self.match # 調(diào)用match方法 返回一個(gè)生成器
- 8 raise StopIteration# 用StopIteration 異常來(lái)判斷for循環(huán)是否結(jié)束
- 9
- 10 def match(self, *args): # 模擬case子句的方法
- 11 if self.fall or not args: # 如果fall為True,則繼續(xù)執(zhí)行下面的case子句
- 12 # 或case子句沒(méi)有匹配項(xiàng),則流轉(zhuǎn)到默認(rèn)分支
- 13 return True
- 14 elif self.value in args: # 匹配成功
- 15 self.fall = True
- 16 return True
- 17 else: # 匹配失敗
- 18 return False
- 19
- 20operator = "+"
- 21x = 1
- 22y = 2
- 23for case in switch(operator): # switch只能用于for... in...循環(huán)中
- 24 if case('+'):
- 25 print (x + y)
- 26 break
- 27 if case('-'):
- 28 print (x - y)
- 29 break
- 30 if case('*'):
- 31 print (x * y)
- 32 break
- 33 if case('/'):
- 34 print (x / y)
- 35 break
- 36 if case(): # 默認(rèn)分支
- 37 print ""
【代碼說(shuō)明】
- 第1行到第18行代碼定義了switch類(lèi),定義了__init__()、__iter__()、match()方法。
- 第23行代碼在for…in…循環(huán)中調(diào)用switch類(lèi),變量operator作為switch類(lèi)的參數(shù)傳遞給構(gòu)造函數(shù)。變量operator的值等于“+”,程序流轉(zhuǎn)到第24行。
- 第25行代碼輸出x + y的結(jié)果。輸出結(jié)果為3。
- 第26行代碼使用break語(yǔ)句中斷switch分支結(jié)構(gòu),程序流轉(zhuǎn)到文件的末尾。