使用者:Xyy23330121/Python/布爾值與 if 語句
布爾值是程序表達判斷結果的方式。總共有兩種布爾值 True
和 False
,分別代表「真(正確)」和「假(錯誤)」。布爾值在以下的內容中起到重要作用。
在編寫程序時,有時會出現需要按情況執行代碼的時候。此時,if 語句很有幫助。我們先看以下示例:
a = 1
if a == 1:
print("注意")
print("a 的值为1")
else:
print("a 的值不为1")
這裡,通過進行 if 語句,我們可以按情況執行代碼。讀者可以嘗試把開頭的 a = 1
改寫為 a = 2
或讓它等於其它內容,看看結果。
以上例子中,以下的代碼構成了一個「語句組」。
if a == 1:
print("注意")
print("a 的值为1")
其中,兩個 print
函數構成了 if
語句的子句。
對於 if
、else
等語句而言,其後必須要跟著子句。當子句只需要一行時,可以不另起一行。以下的方法也是可行的:
if a == 1: print("注意\na 的值为1")
if 語句確認if
後緊跟著的表達式的結果,如果該結果為True
,則執行if
子句,如果該結果為False
,則確認是否有else
語句。如果有else
語句,則執行else
子句。
由上面的討論,if
後緊跟著的表達式必須是一個會返回布爾值的表達式。接下來介紹幾種返回布爾值的表達式。
if
語句的子句也是 if
語句時,如果不換行,會引發語法錯誤。這是因為:
if a > 1: if a < 2: print(a)
else: pass
此時,Python 無法確定該 else
語句是屬於哪個 if
語句的。
Python 通過縮進來確定語句是否是之前語句的子句。縮進就是語句前的空格或 TAB。這裡的兩個 print
函數前面都是4個空格,所以後面的 print
函數不是前面 print
函數的子句——而是和前面函數同級的語句。而 if
前面沒有縮進:縮進少於兩個 print
函數前的縮進,從而這兩個 print
函數都是 if
子句。
如果不分情況亂打空格或 TAB,或者將 TAB 和四個空格混用,就會出現「縮進錯誤」。比如:
a = 1
b = 2
會輸出以下結果:
IndentationError: unexpected indent
這是由於前面的 a = 1
語句並不支持自己有子句導致的。
上面的示例中,我們使用了 a == 1
或 a <= 2
的表達式。本章將詳細講解這些表達式的意義。
以下表格列舉了比較運算的一些運算符:
運算符 | 含義 |
---|---|
< |
小於 |
<= |
小於或等於 |
> |
大於 |
>= |
大於或等於 |
== |
等於 |
!= |
不等於 |
在 Python 中,比如 1 + 2
會輸出 3
,許多表達式是向外輸出一個結果的。比較運算的表達式向外輸出的是布爾類型的布爾值。
比如以下代碼:
print(1 > 2)
1 > 2
與事實不符,因此1 > 2
的表達式會返回False
,從而代碼會輸出:
False
與其它語言不同,python支持比較運算符的任意串聯,比如x < y <= z
只有在x < y
且y <= z
時才會返回True
。
一般來講,只有同為數字,才能進行小於、小於等於、大於、大於等於的比較。對於特殊情況,請參見之後的類的方法與數學運算章節,現在不需要讀者掌握此內容。
浮點數誤差可以十分顯著——顯著到比較運算符會返回錯誤的結果。我們看以下示例:
print(0.1 + 0.2 == 0.3) #输出:False
為此,math 模塊提供了 math.isclose
函數來解決一部分誤差問題。
math.isclose(a, b, *, rel_tol=1e-9, abs_tol=0.0)
當兩個數字 a
和 b
足夠接近時,返回 True
。否則返回 False
。
「足夠接近」是由相對容差 rel_tol
和絕對容差 abs_tol
決定的,具體來講,只要 a
和 b
的差小於以下兩者中的一個,就認為足夠接近:
a
和b
中絕對值較大的那個、其絕對值max(abs(a), abs(b))
和相對容差的乘積。- 絕對容差。
絕對容差對兩者都接近零的情況時很有用:對於默認情況,如果比較 1e-11
和 1e-12
。兩者的差為 9e-12
已經很小,但依舊大於 1e-11 * 1e-9
,並導致該函數返回 False
。讀者應當綜合各種情況正確設置容差。
並非只有比較運算會輸出布爾值,布爾運算也會輸出布爾值。以下是三種布爾運算符:
運算符 | 含義 | 解釋 |
---|---|---|
and |
與 | a and b 只有當a 和b 都為True 時才會輸出True ,否則輸出False
|
or |
或 | a or b 只要a 和b 兩者之一為True 時就會輸出True 。只有兩者都為False ,才會輸出False
|
not |
非 | not a 當a 為True 時輸出False ,當a 為False 時輸出True 。
|
如果我們希望判斷一些複雜情況,就需要用到布爾運算。以下示例展示了「當a < 0 或 b > 1時才執行代碼」:
if a < 0 or b > 1:
print("a < 0 或 b > 1")
從上面的例子也可以看出,布爾運算符比比較運算符的優先級低。正如1 + 2 * 3
會先計算2 * 3
再計算1 + 6
一樣,not True == False
等同於not (True == False)
,因此會輸出True
;而True == not False
會引發錯誤。
在一些情況下,更建議使用比較運算符的串聯。利用串聯可以讓程序少進行一些計算,比如:
1 < 1 + 2 <= 4
在上述計算中,1 + 2
的部分只被計算了一次。而下面的過程
1 < 1 + 2 and 1 + 2 <= 4
中,1 + 2
的部分被計算了兩次。如果中間的運算很複雜,用比較運算符的串聯可以節省大量時間。
語句組中也可以包含 if 語句,我們稱這樣的結構是一種嵌套。以下是一個例子:
if a < 1:
if b > 2:
print("a < 1 且 b > 2")
else:
print("a < 1 且 b <= 2")
else:
if a == 2:
print("a >= 1 且 a == 2")
else:
print("a >= 1 且 a != 2")
嵌套子語句組前的縮進,必須比父語句組要更多。為了方便閱讀以及防止一些莫名其妙的情況,一個項目的代碼要麼每一級縮進都增加四個空格,要麼每一級縮進都增加一個TAB。
為簡便起見,python 將 else 和 if 合為一體。以上的代碼也可以寫為:
if a < 1:
if b > 2:
print("a < 1 且 b > 2")
else:
print("a < 1 且 b <= 2")
elif a == 2:
print("a >= 1 且 a == 2")
else:
print("a >= 1 且 a != 2")
有一些情況不需要考慮縮進,這裡先講第一種情況:括號。
在 Python 中,在括號未閉合時,可以在逗號等運算符處換行。換行後代碼會被當作和換行前的代碼在同一行中,因此不必考慮縮進的問題。比如下面兩個代碼,運行的結果是完全相同的:
print("两数字相加的结果为:", float(input("请输入第 1 个数字:")) + float(input("请输入第 2 个数字:")))
print("两数字相加的结果为:",
float(input("请输入第 1 个数字:"))
+ float(input("请输入第 2 个数字:")))
而對同一行代碼,Python 會忽略表達式中的TAB和空格,所以可以隨意添加縮進。比如,以下代碼和上面兩個代碼,運行結果也是相同的:
print("两数字相加的结果为:",
float(input("请输入第 1 个数字:"))
+ float(input("请输入第 2 个数字:")))
但是要注意,不能在變量中間換行,比如:
print("两数字相加的结果为:",
float(input("请输入
第 1 个数字:"))
+ float(input("请输入
第 2 个数字:")))
由於字符串中間被視為是斷開了,這裡會報錯。
條件表達式(也被稱為:三元運算符)具有類似 if 語句的功能。我們有以下示例:
print("正确时的输出" if 0 < 1 else "错误时的输出") #输出:正确时的输出
print("正确时的输出" if 0 > 1 else "错误时的输出") #输出:错误时的输出
當條件表達式中,if
和else
之間的部分返回True
時,條件表達式會輸出if
左邊的內容。反之,會輸出else
右邊的內容。條件表達式的運算順序高於且僅高於賦值的=
、+=
、:=
等以及用於匿名函數的lambda
表達式,所以基本不需要添加括號。
lambda
表達式將在之後的章節學習。讀者此時並不需要掌握這些內容。