深入理解 Python and 邏輯運算符(踩坑)

来源:https://www.cnblogs.com/panlq/archive/2023/09/08/17687294.html
-Advertisement-
Play Games

# ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/98edff345fb44c9ca30237fa7958f6f8~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1920&h=1080&s=72 ...


1. 引子

def enabled() -> bool:
    a = ["a,"b"]
	b = True
    c = False
    return (b and c) or (b and a)

以上代碼返回什麼?

實際生產項目踩到的坑,也怪自己沒理解到未,才疏學淺!!!

想當然的以為 python 自己會做真值判斷了。其實真值判斷是在 if 條件語句時會生效,但在普通的 and 的運算符下有另外一個規則。

2. python bool 類型簡述

“The Boolean type is a subtype of the integer type, and Boolean values behave like the values 0 and 1, respectively, in almost all contexts, the exception being that when converted to a string, the strings ‘False’ or ‘True’ are returned, respectively.”

“布爾類型是整數類型的一個子類型,在幾乎所有的上下文環境中布爾值的行為類似於值0和1,例外的是當轉換為字元串時,會分別將字元串”False“或”True“返回。“

就python而言,True,1和1.0都表示相同的字典鍵

>>> True == 1 == 1.0
True
>>> (hash(True), hash(1), hash(1.0))
(1, 1, 1)

>>> issubclass(bool, int)
True
>>> isinstance(True, int)
True
>>> isinstance(False, int)
True
>>> int(True)
1
>>> int(False)
0

>>> help(bool)

Help on class bool in module builtins:

class bool(int)
    |  bool(x) -> bool
    |
    |  Returns True when the argument x is true, False otherwise.
        |  The builtins True and False are the only two instances of the class bool.
        |  The class bool is a subclass of the class int, and cannot be subclassed.

3. bool類型之間的 and 運算

and 運算符有兩個操作數,可以是 bool,object,或一個組合

>>> True and True
True

>>> False and False
False

>>> True and False
False

>>> False and True
False

以上示例表明,僅當表達式中的兩個操作數都為 true 時,和表達式才返回 True。由於 and 運算符需要兩個操作數來構建表達式,因此它是一個二元運算符。

當兩邊操作書都為 bool 類型時,二元操作運算結果如下。

operand1 operand2 operand1 and operand2
True True True
True False False
False False False
False True False

當然,以上的結果也適用於兩邊操作數一個 bool 表達式的情況。

expression1 and expression2

>>> 5>3 and 5==3+2
True

4. 不同類型之間的 and 運算

可以使用 and 運算符在單個表達式中組合兩個 Python 對象。在這種情況下,Python 使用內部的bool() 來判斷操作數的真值。此時,兩個對象之間的運算,結果將獲得一個特定的對象,而不是布爾值。僅當給定操作數顯式計算為 True 或 False 時,才會獲得 True 或 False

>>> 2 and 3
3
>>> 5 and 0.0
0.0
>>> [] and 3
[]
>>> 0 and {}
0
>>> 1 and {}
{}
>>> False and ""
False
>>> True and ""
''
>>> ["a"] and [1]
[1]

根據以上測試用例結果,當and運算結果為 False 時返回左操作數,當and運算結果為 True 時返回右操作數

關於真值的判斷規則,在 python 的文檔中有說明

Any object can be tested for truth value, for use in an if or while condition or as operand of the Boolean operations below.

By default, an object is considered true unless its class defines either a bool() method that returns False or a len() method that returns zero, when called with the object. 1 Here are most of the built-in objects considered false:

  • constants defined to be false: None and False
  • zero of any numeric type: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
  • empty sequences and collections: '', (), [], {}, set(), range(0)

https://docs.python.org/3/library/stdtypes.html#truth-value-testing

以下是對象之間的比較結果集

object1 object2 object1 and object2
False False object1
False True object1
True True object2
True False object2

綜上:如果 and 表達式中的操作數是對象而不是布爾表達式,則運算符在計算結果為 False 時返回左側的對象。否則,它將返回右側的對象,即使其計算最終結果為 False。

⚠️:如果在做對象邏輯運算,最終結果想得到 bool 類型 True/False的話,可以使用內建函數 bool(expression) 將結果重新實例化一下在返回

5. 高效運算-“快速短路”(short-circuit operator)

短路操作器,聽這個名字就知道是快速運算,Python 的邏輯運算符,如 and and or,使用稱為短路求值或惰性求值的東西來加速運算,高效得到結果。

例子:為了確認 and 表達式的最終結果,首先計算左操作數,如果它是False,那麼整個表達式都是False。在這種情況下,無需計算右側的操作數,就已經知道最終結果了

>>> def true_func():
...     print("Running true_func()")
...     return True
...

>>> def false_func():
...     print("Running false_func()")
...     return False
...

>>> true_func() and false_func()  # Case 1
Running true_func()
Running false_func()
False

>>> false_func() and true_func()  # Case 2
Running false_func()
False

>>> false_func() and false_func()  # Case 3
Running false_func()
False

>>> true_func() and true_func()  # Case 4
Running true_func()
Running true_func()
True

短路操作器,是提升代碼性能的一種有效手段。在邏輯運算表達式時,可考慮如下兩個原則:

  1. 將耗時的表達式放在 and 關鍵字的右側。這樣,如果短路規則生效,則不會運行代價高昂的表達式。
  2. 將更有可能為 false 的表達式放在 and 關鍵字的左側。這樣, 更有可能通過僅計算左操作數來確定整個表達式是否為 false。

當然,如果一定要執行運算符兩邊的表達式,則可以使用位運算符號 (&, |, ~),替代邏輯運算符

>>> def true_func():
...     print("Running true_func()")
...     return True
...

>>> def false_func():
...     print("Running false_func()")
...     return False
...

>>> # Use logical and
>>> false_func() and true_func()
Running false_func()
False

>>> # Use bitwise and
>>> false_func() & true_func()
Running false_func()
Running true_func()
False

6. bool 邏輯運算的萬能公式

Operation Result Notes
法則 1 x or y if x is true, then x, else y 1
法則 2 x and y if x is false, then x, else y 2
法則 3 not x if x is false, then True, else False 3

Notes:

  1. This is a short-circuit operator, so it only evaluates the second argument if the first one is false.
  2. This is a short-circuit operator, so it only evaluates the second argument if the first one is true.
  3. not has a lower priority than non-Boolean operators, so not a == b is interpreted as not (a == b), and a == not b is a syntax error.

多複雜的組合表達式,最終都可以一重重拆解成一個個獨立的小單元,在做合併

就拿開頭的引子來說

def enabled() -> bool:
    a = ["a,"b"]
	b = True
    c = False
    return (b and c) or (b and a)

拆成三步來看

  1. b and c --> 運用法則 2 (if x is false, then x, else y) 所以結果是 c 即 False
  2. b and a --> a 運用法則 2 (if x is false, then x, else y) 所以結果是 a 即 ["a", "b"]
  3. False or ["a", "b"] 運用法則 1 (if x is true, then x, else y) 所以結果是 ["a", "b"]

7. 參考

  1. python-and-operator
  2. python-docs-truth-value-testing
  3. Python3 源碼閱讀 數據類型-Int.md

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • # Python初步瞭解裝飾器 - 裝飾器的概念 - 裝飾器的簡單使用 - 裝飾器的進階 - 裝飾器的練習 - 裝飾器的固定模塊 - 裝飾器的語法糖 ## 裝飾器的概念 ```python 裝飾器它不是一個新的知識點,它是有之前我們學習的名稱空間、函數嵌套、閉包函數等知識點彙總而來 器:工具 裝飾: ...
  • 在軟體開發中,我們經常會遇到這樣的情況:我們需要使用一個現有的類或者介面,但它與我們系統的目標介面不相容,而我們又不能修改它。這時候,我們該怎麼辦呢?大多數情況下我們都可以使用適配器模式來解決這個問題,**本文將從以下四個方面講解適配器模式**。 - 簡介 - 優缺點 - 應用場景 - Java 代 ...
  • ## 1. 什麼是Http2.0 HTTP/2.0,通常簡稱為HTTP/2,是一種用於傳輸超文本(例如網頁和資源文件)的網路協議。它是HTTP/1.1的繼任者,旨在提高性能和效率,以適應現代Web應用的需求。HTTP/2的主要特點包括以下幾點: 1. **多路復用(Multiplexing)**:H ...
  • 光看訪客這個名字,猜測這個訪客模式應該非常好理解,只要玩過Linux的人,都能深刻明白Root和非Root和訪客賬號登錄的巨大差別性。 # What is Visitor? 如果你沒玩過Linux,那麼假設公共的圖書館有一臺電腦,有兩個賬戶: - 其中一個是**管理員(Admin)**的賬戶,擁有這 ...
  • 作者:是奉壹呀 \ 來源:juejin.cn/post/7262274383287500860 看到一個評論,裡面提到了list.sort()和list.strem().sorted()排序的差異。 說到list sort()排序比stream().sorted()排序性能更好,但沒說到為什麼。 ! ...
  • Sermant是基於Java位元組碼增強技術的無代理服務網格,其利用Java位元組碼增強技術為宿主應用程式提供服務治理功能。 ...
  • 京東茅臺搶購腳本可以分為以下幾部分,具體實現步驟如下: 登錄京東賬號 首先需要登錄京東賬號。一個簡單的方式是使用Python的 selenium 庫。在使用 selenium 庫前,需要安裝 selenium 庫和對應的瀏覽器驅動。 示例代碼如下所示: from selenium import we ...
  • # It can explain what ? 如下是解釋器要解釋的主體: - 加減乘除等運算,3+4/9+6*8 - 摩爾斯電碼 - 正則表達式 - El表達式 - OGNL表達式 - 小明是北京人 - 小紅是一名售貨員 - 部門領導下發一則通知 - ... # How explain ? 解釋器 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...