使用者:Xyy23330121/Python/布爾值與 if 語句


布爾值是程序表達判斷結果的方式。總共有兩種布爾值 TrueFalse ,分別代表「真(正確)」和「假(錯誤)」。布爾值在以下的內容中起到重要作用。

if 語句

編輯

在編寫程序時,有時會出現需要按情況執行代碼的時候。此時,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 語句的子句。

對於 ifelse 等語句而言,其後必須要跟著子句。當子句只需要一行時,可以不另起一行。以下的方法也是可行的:

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 == 1a <= 2 的表達式。本章將詳細講解這些表達式的意義。

以下表格列舉了比較運算的一些運算符:

運算符 含義
< 小於
<= 小於或等於
> 大於
>= 大於或等於
== 等於
!= 不等於

在 Python 中,比如 1 + 2 會輸出 3 ,許多表達式是向外輸出一個結果的。比較運算的表達式向外輸出的是布爾類型的布爾值。

比如以下代碼:

print(1 > 2)

1 > 2與事實不符,因此1 > 2的表達式會返回False,從而代碼會輸出:

False

與其它語言不同,python支持比較運算符的任意串聯,比如x < y <= z只有在x < yy <= z時才會返回True

一般來講,只有同為數字,才能進行小於、小於等於、大於、大於等於的比較。對於特殊情況,請參見之後的類的方法與數學運算章節,現在不需要讀者掌握此內容。

math.isclose

編輯

浮點數誤差可以十分顯著——顯著到比較運算符會返回錯誤的結果。我們看以下示例:

print(0.1 + 0.2 == 0.3) #输出:False

為此,math 模塊提供了 math.isclose 函數來解決一部分誤差問題。

math.isclose(a, b, *, rel_tol=1e-9, abs_tol=0.0)

當兩個數字 ab 足夠接近時,返回 True。否則返回 False

「足夠接近」是由相對容差 rel_tol 和絕對容差 abs_tol 決定的,具體來講,只要 ab 的差小於以下兩者中的一個,就認為足夠接近:

  1. ab 中絕對值較大的那個、其絕對值 max(abs(a), abs(b)) 和相對容差的乘積。
  2. 絕對容差。

絕對容差對兩者都接近零的情況時很有用:對於默認情況,如果比較 1e-111e-12。兩者的差為 9e-12 已經很小,但依舊大於 1e-11 * 1e-9,並導致該函數返回 False。讀者應當綜合各種情況正確設置容差。

布爾運算

編輯

並非只有比較運算會輸出布爾值,布爾運算也會輸出布爾值。以下是三種布爾運算符:

運算符 含義 解釋
and a and b只有當ab都為True時才會輸出True,否則輸出False
or a or b只要ab兩者之一為True時就會輸出True。只有兩者都為False,才會輸出False
not not aaTrue時輸出False,當aFalse時輸出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 語句,我們稱這樣的結構是一種嵌套。以下是一個例子:

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 "错误时的输出")  #输出:错误时的输出

當條件表達式中,ifelse之間的部分返回True時,條件表達式會輸出if左邊的內容。反之,會輸出else右邊的內容。條件表達式的運算順序高於且僅高於賦值的=+=:=等以及用於匿名函數的lambda表達式,所以基本不需要添加括號。

lambda表達式將在之後的章節學習。讀者此時並不需要掌握這些內容。