Python運算符優先級詳細整理

前言

雖然本文講的是Python,但其實它也適用於所有的編程語言。因為這裡面蘊含著編程之魂。所以本文標題沒有顯著的使用Python關鍵詞。當然以前的文章用瞭Python關鍵詞是因為當時我並沒有想到這一點,很多內容也適用所有編程語言。

本文是運算符相關教程的最後一篇,將介紹運算符的最後一個匯總性的概念——運算符的優先級。

優先級概述

所謂優先級,是指優先計算的順序。比如小學中我們學過的加減乘除基本四則運算,乘除要先於加減計算,因為乘除的優先級比加減要高。小括號擁有最高優先級,如果想先計算加減,可用小括號將其包圍起來,在Python中也是如此,很顯然,計算順序不同,其結果也是不同的:

相同優先級

有些運算是互逆的,交換它們的位置不影響運算結果,所以區分它們的優先級是沒有必要的,比如加和減(包括正號和負號)、乘和除、左移和右移、is與is not、in與not in。這些運算符都具有相同的優先級。

當然,有些運算符交換位置會影響結果,但它們本身隻是表示同一種算法的不同結果,難以區分不同的優先級。比如比較運算符中的等於、大於、小於、不等於、大於等於、小於等於都具有相同的優先級。

需要特別註意的是,雖然Python支持諸如下例所示的連續的比較運算符:

a > b == c

但它其實是 a > b and b == c 的簡略寫法,而不是表示先進行計算 a > b ,然後用結果判斷是否等於c,也不是判斷a是否大於 b == c 的結果,下面的示例可以證明這點,無論哪個運算符先計算,其結果都與原始表達式結果不同,隻有轉換成兩個表達式才一樣(註:False等價於0,True等價於1):

這一點,對於<等其他比較運算符,規則也是如此。

當然,大多數運算符的優先級是不同的。

結合性

與運算符優先級相關的另一個重要概念是結合性,它決定瞭同一種運算符是從左往右計算,還是從右往左。下面是一個優秀的著名例子:

 它證明乘方運算的結合性是從右往左。

大多數運算符都是從左往右開始計算的,簡稱左結合性。隻有少部分運算符具有右結合性。下面是右結合性運算符列表:

按位取反(位非)、正負號、位與、邏輯非、賦值系列運算符

運算符優先級一覽表

其中上一行比下一行的優先級高,同一行表示優先級相同。在同一個表達式中,按照優先級從高到低依次計算,優先級相同則按照從左到右的順序計算。同一類型的運算符則按結合性計算。

註:其中@為矩陣乘法運算符,大多數資料中都沒有記錄此運算符。官方文檔記錄:“The @ (at) operator is intended to be used for matrix multiplication. No builtin Python types implement this operator.”(@(at)運算符打算用於矩陣乘法。沒有任何內置的Python類型可以實現此操作符。)

賦值系列運算符的優先級最低,比or還要低:

另外賦值運算符支持連續的賦值,這和比較運算符類似,但其實也是相當於兩個分開的賦值,與優先級無關:

本表參考於Python3.7.3官方文檔:

Python3.10.4官方文檔也一樣,但是沒有前者友好,順序是相反的:

 運算符優先級重點說明

運算符優先級的概念並不需要去刻意地記憶,如果對某個運算符的優先級不太確定,可以使用小括號將其包圍起來。

當然,記住一些重要的優先級概念,有助於對程序的閱讀理解與編寫維護。下面是一些重要的優先級:

小括號具有最高優先級。

運算符優先級按類別排序:算術 > 位 > 身份 >成員 > 比較 > 邏輯 > 賦值。 算術最高,賦值被低。位非運算符是個另外,它高於乘除。

身份、成員、比較、賦值運算符,同類中優先級相同。

算術運算符中:乘方最高,乘除整除取餘次之,加減最低。

位運算符中:位非 > 左右移 > 位與 > 位異或 > 位或

邏輯運算符中:非最高,與次之,或最低。

另外,我沒有聽說過任何編程語言有降低運算優先級——與小括號功能正好相反的運算符。這應該是沒有必要的,因為根據相對性原理,給一個運算符最高優先級,就相當於給其他運算符最低優先級瞭,所以,如果想給一個運算符最低的優先級,可以將其餘的運算符全部用小括號包圍起來。

最後,除瞭可以用於提高運算符的優先級之外,在Python中,小括號還有另外一個重要的功能——做為元組的定界符。

身為Python特有的四大基本數據類型之一,元組(tuple)已經在本教程中出現過很多次瞭,在以後還會出現更多次,所以,下一篇將正式介紹元組。敬請關註。

結語

通過本文的編寫,我意識到自己對Python的認知還有很大的局限——我剛剛才得知Python中有@矩陣乘法運算符!

雖然我接觸編程已有14年瞭,初識Python也有五六年瞭,使用Python編寫的大大小小的程序工程也有近百個,但是如果不是今天對網上運算符優先級資料正確性的質疑,沒有查看官方文檔的話,不知道還要多少年之後才會得知這一點。

我以前無論找到的與運算符相關還是運算符優先級相關的Python資料都沒有提到@,這也說明網上絕大部分的資料的正確性也需要證明。比如關於乘方運算符的右結合性,網絡上大多資料都錯誤的記錄為左結合性。

我寫作這樣的文章也很困難,因為我吹毛求疵的性格要求我必須寫出全網獨一無二的最優秀的精品內容,獨一無二是很容易的,我的任何一篇文章都有自己獨特的理解,並不是簡單的對其他地方資料的搬運整合,最優秀就非常困難瞭,這不僅需要無私的分享精神,更需要卓越的洞察與理解能力,我正在朝這個方向努力。

如果不能做到這一點,我覺得就沒有寫出來的必要,雖然我的文章點擊率很低,但最近的文章都有近十分之一的閱讀收藏率證明瞭讀者對它的認可,這也是頭條給予1萬推薦的原因所在,否則至多100個推薦就到頭瞭。

到此這篇關於Python運算符優先級的文章就介紹到這瞭,更多相關Python運算符優先級內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: