python避免深度嵌套的if-else_【python程式風格談】if-else的邏輯處理技巧

在程式語言中,我們經常需要做條件判斷,

「如果...就做...」,

if-else在程式碼中出現的比率應該算是相當高的,

然而在python中的if-else怎麼寫是很有學問的,

過於多層的if-else嵌套,

容易使程式邏輯複輯,難以除錯

這一篇從語法及邏輯出發,教大家如何避免寫出冗長的if-else

技巧1- 布林值本身不要再包一層if-else了

舉個簡單的例子,

例如希望寫一個函數判斷一個整數是否是偶數,

經驗不足的人可能會順手寫出以下程式:

def isEven(n):

if n%2 == 0:

return True

else:

return False

看起來是沒有什麼問題,

但其實n%2 == 0本身是一個條件判斷式,

n%2 == 0 的值已經是True或是False了,

因此這段程式可以簡單用一句話來寫:

def isEven(n):

return n%2 == 0

技巧2 – 三元運算式語法

三元運算式的語法為:

變數 = 值1 if 條件式 else 值2

如果條件式的值為True,變數就會等於值1,

否則變數等於值2。

注意使用三元運算子語法時,

if-else一定要成對出現。

例如現在我們想要判斷一個變數型態是否為整數,

我們可以用type()函數檢查一個變數的型態。

化簡前:

n = 5

T=""

if type(n)==int:

T="n是整數"

else:

T="n不是整數"

化簡後:

n = 5

T= "n是整數" if type(n)==int else "n不是整數"

這樣寫的好處不光是程式碼變短了,

還能避免撰寫重複的程式碼,

原本你的T=共寫了兩次,

化簡後T=只要寫一次,

萬一變數名稱有變動的時候,

才不會改了第一個忘記改第二個

NG範例:

if type(n)==int:

t="n是整數" # 變數t改成小寫,下面的else區塊卻忘記同步改

else:

T="n不是整數"

技巧3 – 利用in合併多個條件式

in這個關鍵字除了平時較常用的與for搭配的語法外(例如for i in range(3):),

亦可作為條件判斷,

A in B即是判斷物件A是否在容器B裡,

例如:

>>> 1 in [1,2,3]

True

>>> "a" in "apple"

True

例如現在給你一個單字,

要你判斷這個單字的字首是不是母音('a','e','i','o','u')。

化簡前:

word = "apple"

if word[0] == 'a' or word[0] == 'e' or word[0] == 'i' or word[0] == 'o' or word[0] == 'u':

print("單字開頭為母音")

五個判斷式同樣以word[0]這個字來做等式判斷,

實在太冗長了。

可以用in做改寫會簡單許多。

化簡後:

word = "apple"

if word[0] in 'aeiou':

print("單字開頭為母音")

這樣寫的好處不光是語法精簡,

同上面的道理,避免重複的程式碼word[0] ==寫很多次,

難保說複製貼上多次,

需求改變的時候,

你會不會有小地方忘記改到

NG範例(這邊改成判斷單字尾巴為母音,其中打字疏忽,word[0] == 'o'漏改為word[-1] == 'o') :

word = "apple"

if word[-1] == 'a' or word[-1] == 'e' or word[-1] == 'i' or word[0] == 'o' or word[-1] == 'u':

print("單字結尾為母音")

技巧4 – 利用列表或字典化簡大量if-elif

範例: 十二生肖

民國1年是鼠年,

想要寫一個程式判斷今年是什麼年(鼠、牛、虎、兔、…)。

化簡前:

year = int(input())

if year%12 == 1:

print("今年是鼠年")

elif year%12 == 2:

print("今年是牛年")

elif year%12 == 3:

print("今年是虎年")

# …

#省略部分程式碼

# …

elif year%12 == 11:

print("今年是狗年")

elif year%12 == 0:

print("今年是豬年")

哇,光是判斷十二生肖就寫了12個if-elif了,

其實像這類有大量if-elif,但裡面做的事相同(同樣是print一個字串),

便適合用list或dict建立對應關係

化簡後:

year = int(input())

S = ["豬","鼠","牛","虎","兔","龍","蛇","馬","羊","猴","雞","狗"]

print("今年是"+S[year%12]+"年")

改成用列表取index的方式來做,

把if-elif全部省略了,

是不是非常簡潔易讀呢?

範例: 撲克花色

假設我們想把英文字母與撲克牌的花色做轉換,

且看以下程式:

化簡前:

letter = input()

suit = ""

if letter == 's':

suit = "黑桃"

elif letter == 'h':

suit = "紅心"

elif letter == 'd':

suit = "方塊"

elif letter == 'c':

suit = "梅花"

這時便很適合用python的字典化簡它。

化簡後:

letter = input()

D = {'s':"黑桃", 'h':"紅心", 'd':"方塊", 'c':"梅花"}

suit = D[letter]

技巧5 – 化簡多重嵌套if-else

首先提一下什麼是嵌套的if-else,

簡單來說就是if區塊裡面又包了一層if,

例如以下例子,假設我們想要根據學生的分數,

印出不同的字串給序回饋:

score = int(input('請輸入你的分數: '))

if score>100 or score<0:

print('輸入的成績不合法')

elif score>60:

if 85<=score<=89:

print('你真棒,差一點就可以A+了')

elif score>=99:

print('哇塞,你是神人吧')

else:

print('恭喜你及格,不用重補修')

else:

print('好課值得一修再修,明年請再重修這門課')

這個例子只有兩層if-else,

故且還看的懂,

然而在真實專案中,偶有工程式寫到三、五層嵌套if-else,

每個if-else區塊中還有上百行程式碼,

這時讀程式碼的人就會讀的很痛苦

請避免在程式碼中寫出嵌套的if-else,

真的難以避免的話,請以兩層if-else為限,

以免超過人類適合閱讀的邏輯

<上述程式優化方案>

首先,將有嵌套邏輯的地方改包裝成函數,

def jugdeStr(score):

# 根據score 回傳適當的字串評語

if score>100 or score<0:

return '輸入的成績不合法'

elif score>60:

if 85<=score<=89:

return '你真棒,差一點就可以A+了'

elif score>=99:

return '哇塞,你是神人吧'

else:

return '恭喜你及格,不用重補修'

else:

return '好課值得一修再修,明年請再重修這門課'

score = int(input('請輸入你的分數: '))

print(jugdeStr(score))

在函數中,碰到return就會跳出函數,

因此常常可以拆解雙層if-else邏輯,

變成僅有單層的if

化簡後:

def jugdeStr(score):

# 根據score 回傳適當的字串評語

if score>100 or score<0:

return '輸入的成績不合法'

if 85<=score<=89:

return '你真棒,差一點就可以A+了'

if score>=99:

return '哇塞,你是神人吧'

if score>60:

return '恭喜你及格,不用重補修'

return '好課值得一修再修,明年請再重修這門課'

score = int(input('請輸入你的分數: '))

print(jugdeStr(score))

化簡後的函數一個else都不需要寫,

而且邏輯流程會清晰許多

經典題分享- 判斷閏年

判斷閏年可能是新手練程式常做到的一道題,

在曆法中,

若n是4的倍數但不是100的倍數,

或者n是400的倍數,

則n 為閏年。

希望實作一個函數輸入數字n,

回傳n是否為閏年

由於閏年的描述較為複雜,

經驗不足很容易就寫成嵌套邏輯,

弄的相當複雜:

def isLeapYear(n):

if n%4==0:

if n%100!=0:

return True

else:

if n%400 ==0:

return True

else:

return False

else:

return False

然而此函數其實可以寫的相當乾淨簡潔:

def isLeapYear(n):

return (n%4==0 and n%100!=0) or n%400==0

此例留給大家欣賞學習

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值