【Python】詳解 邏輯運算符 (and、or、not) + 布爾邏輯 (bool)

目錄

一、緒論

二、說明

2.1 關於 bool 邏輯值 (十分重要)

2.2 and —— bool “與” 邏輯運算符

2.3 or —— bool “或” 邏輯運算符

2.4 not —— bool “非” 邏輯運算符

2.5 邏輯運算符混用與優先級等問題


一、緒論

以前看過的一些教程及網上資源對 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 邏輯運算,但並不總是返回 TrueFalse,而是返回用於比較的值之一。

使用 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 邏輯運算,但並不總是返回 TrueFalse,而是返回用於比較的值之一。

使用 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 邏輯運算,只返回 TrueFalse,注意區別!

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

總而言之,對於邏輯運算符的使用,在理解設計和運行原理的前提下,結合圓括號 () 鎖定優先級,就不太會出什麼岔子了~


參考文獻:

https://www.runoob.com/python/python-operators.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章