目錄
一、緒論
以前看過的一些教程及網上資源對 Python 邏輯運算符部分的敘述都很簡單,給出定義加上幾個小例子就完事了。然而,後來才發現事情比想象中的要複雜一些,還是希望整理清楚一些。^ ^
運算符 | 邏輯表達式 | 簡要說明 |
and | x and y | 布爾"與" - 若 x 爲 False,x and y 返回 False,否則返回 y 的計算值 |
or | x or y | 布爾"或" - 若 x 爲非 0,則返回 x 的值,否則返回 y 的計算值 |
not | not x | 布爾"非" - 若 x 爲 True,返回 False;若 x 爲 False,返回 True |
二、說明
2.1 關於 bool 邏輯值 (十分重要)
關於 變量/對象 的 bool 邏輯值,通常只有 0、''、[]、()、{}、None、False 爲 False,其餘均爲 True。
對於 類實例,默認爲 True,但也可自定義方法使運算值爲 False (如 return False)。
關於其他 布爾表達式,則取決於其運算結果的 bool 邏輯。
# 使用 bool() 函數判斷變量/對象、表達式、類實例等的 bool 邏輯值
>>> bool(0)
False
>>> bool('')
False
>>> bool([])
False
>>> bool(())
False
>>> bool({})
False
>>> bool(None)
False
>>> bool(False)
False
>>> bool(1>2)
False
>>> bool(1<2)
True
>>> bool(1==2)
False
>>> bool(1 is 2)
False
>>> bool(1 is not 2)
True
>>> bool(1 in [1, 2])
True
>>> bool(1 not in [1, 2])
False
關於 bool 邏輯表達式,遠不止上述種類,許多 Python 關鍵字的使用都能構造出來。
然而,有一種流行的錯誤說法是:邏輯運算符用於操作 bool 類型的表達式,執行結果也是 bool 類型。事實上,Python 邏輯運算符可用於任何類型的表達式,表達式爲 bool 類型只是充分不必要條件;同時,邏輯運算的結果可爲任意類型,而不一定是 bool 類型,(注意,準確地說,用於運算的表達式及其結果的 bool 邏輯值是一定爲 True 或 False) 例如:
# 只要 bool 邏輯值爲 True 或 False 之一, 無論什麼類型都能使用邏輯運算符
>>> 1 and 'csgo'
'csgo'
>>> [6,6,6] or [8,8,8]
[6, 6, 6]
>>> not {"C", "T"}
False
# 用於運算的表達式, 其 bool 邏輯值一定爲 True 或 False
>>> bool(1)
True
>>> bool('csgo')
True
>>> bool([6,6,6])
True
>>> bool([8,8,8])
True
>>> bool({"C", "T"})
True
此外,還有一些 sao 操作,但沒事不建議這麼寫,有興趣可以看一下:
>>> True == 1 # 就是這麼定的, 因爲 bool 型是 int 型的一個子類
True
>>> False == 0
True
>>> True + 1 # 就是這麼算的 —— bool 值的非 bool 運算
2
>>> True + False
1
還有一道經典題 (LeetCode) 不得不提:
求 1+2+...+n ,要求不能使用乘除法、for、while、if、else、switch、case 等關鍵字及條件判斷語句 (A?B:C)。
示例 1:
輸入: n = 3
輸出: 6
限制: 1 <= n <= 10000
# 利用 bool 值是 int 子類和邏輯運算符的短路特性, 光速解題
def sumNums(self, n: int) -> int:
return n and (n + sumNums(n-1))
2.2 and —— bool “與” 邏輯運算符
已知 and 雖執行 bool 邏輯運算,但並不總是返回 True 或 False,而是返回用於比較的值之一。
使用 and 時,從左到右進行邏輯運算 (判定輸出結果)。一旦遇到 bool 邏輯爲 False 的值,則立刻返回該值且不再往後運算;否則,所有元素的 bool 邏輯值均爲 True,and 將返回最後一個值。
爲什麼是這樣的呢?不難理解,按照“與”邏輯 —— “全真才真,一假即假”,爲判斷 and 表達式中是否存在 bool 邏輯爲 False 的值,需要從左往右遍歷,依次判斷是否有“假”。一旦遇到 bool 邏輯爲 False 的“假貨”,則返回它 (而不一定返回 False !),相當於宣告了 and 表達式爲假,不論後面有什麼也無需再往後演算 (短路操作)。如果一直遇到“真貨”直至結束,則返回最後一個值 (而不一定返回 True !),相當於宣告了 and 表達式爲真。
# 從左到右依次演算, 一旦遇到 bool 爲 False 的值, 立即返回之, 不再往後演算
>>> 1 and 0 and [] and None
0
>>> 1 and '' and {} and () and False
''
# 若 bool 上下文中所有值均爲 True, 則返回從左到右的最後一值
>>> 1 and 2 # 返回最後一個 2
2
>>> 1 and 2 and 3 and 4 # 返回最後一個 4
4
除了 2.1 節的 LeetCode 題,and 的用處還很多,例如: 判斷一個 list 末端元素是否 >0,由於不確定 list 是否爲空,直接下標索引取值可能會引發 error。如果不想多寫個 if 判斷 list 是否非空,可以這麼寫:
>>> lst = []
>>> if lst[-1]>0:
print("last element > 0")
Traceback (most recent call last):
File "<pyshell#95>", line 1, in <module>
if lst[-1]>0:
IndexError: list index out of range
>>> if lst and lst[-1]>0:
print("last element > 0") # 如此即便 lst 爲空也不會拋出異常
2.3 or —— bool “或” 邏輯運算符
已知 or 雖也執行 bool 邏輯運算,但並不總是返回 True 或 False,而是返回用於比較的值之一。
使用 or 時,從左到右進行邏輯運算 (判定輸出結果)。一旦遇到 bool 邏輯爲 True 的值,則立刻返回該值且不再往後運算;否則,所有元素的 bool 邏輯值均爲 False,or 將返回最後一個值。
爲什麼這樣呢?同樣不難理解,按照“或”邏輯 —— “一真即真,全假才假”,爲判斷 or 表達式中是否存在 bool 邏輯爲 True 的值,需要從左往右遍歷,依次判斷是否有“真”。一旦遇到 bool 邏輯爲 True 的“真貨”,則返回它 (而不一定返回 True !),相當於宣告了 or 表達式爲真,不論後面有什麼也無需再往後演算 (短路操作)。如果一直遇到“假貨”直至結束,則返回最後一個值 (而不一定返回 False !),相當於宣告了 or 表達式爲假。
# 從左到右依次演算, 一旦遇到 bool 爲 True 的值, 立即返回之, 不再往後演算
>>> 1 or 2
1
>>> 1 or 2 or 3 or 0
1
# 若 bool 上下文中所有值均爲 False, 則返回從左到右的最後一值
>>> 0 or False # 返回最後一個 False
False
>>> '' or {} or () # 返回最後一個 ()
()
>>> 0 or [] or None # 無顯式返回 (返回最後一個 None)
2.4 not —— bool “非” 邏輯運算符
not 執行 bool 邏輯運算,只返回 True 或 False,注意區別!
not 運算符用起來簡單,若元素的 bool 邏輯值爲 True,則 not 表達式返回 False;若元素的 bool 邏輯值爲 False,則返回 True。一言以蔽之 —— 跟你唱反調...
# 一目瞭然, 無需多言
>>> not 1
False
>>> not 0
True
>>> not [6,6,6]
False
>>> not []
True
2.5 邏輯運算符混用與優先級等問題
注意,Python 的 bool 邏輯運算符是 and、or、not,而非 &、||、~ (後三者作爲二進制位運算的邏輯與、或、非)。
以上說明的 and 及 or 的運算順序都是從左往右,但這都是在沒有圓括號 “()” 和邏輯運算符混用的前提下的簡單情況。
如果存在更復雜的情況,則存在運算優先級:() > not > and > or
本文將不會給出任何不使用圓括號 () 的混用例子,因爲這樣極易造成干擾和混淆,爲解讀和修正帶來困擾,你這麼寫一定會被人錘死的~ 非要混用,就記住一定要用圓括號 () 保障優先級和可讀性!
>>> 1 and (2 or 3) # (2 or 3) 結果爲 2 → 1 and 2 結果爲 2
2
>>> 4 or (5 and 6) # (5 and 6) 結果爲 6 → 4 or 6 結果爲 4
4
通常情況下,邏輯運算符是和比較運算符一起使用的,同樣都用於條件選擇和循環。
# 規範書寫
>>> (x>0) and (y>0)
True
>>> (x==1) or (y==1)
True
>>> not (x<0)
True
總而言之,對於邏輯運算符的使用,在理解設計和運行原理的前提下,結合圓括號 () 鎖定優先級,就不太會出什麼岔子了~
參考文獻: