《Python从小白到大牛》第7章 运算符
《Python從小白到大牛》已經上市!
本章為大家介紹Python語言中一些主要的運算符(也稱操作符),包括算術運算符、關系運算符、邏輯運算符、位運算符和其他運算符。
算術運算符
Python中的算術運算符用來組織整型和浮點型數據的算術運算,按照參加運算的操作數的不同可以分為一元運算符和二元運算符。
一元運算符
Python中一元運算符有多個,但是算數一元運算符只有一個,即:-,-是取反運算符,例如:-a是對a取反運算。
在Python Shell中運行示例代碼如下:
>>> a = 12 >>> -a -12 >>>上述代碼是把a變量取反,結果輸出是-12。
二元運算符
二元運算符包括:+、-、*、/、%、**和//,這些運算符主要是對數字類型數據進行操作,而+和*可以用于字符串、元組和列表等類型數據操作。具體說明參見表7-1。
表 7?1二元算術運算符
| + | 加 | 可用于數字、序列等類型數據操作。對于數字類型是求和;其他類型是連接操作。 | a + b |
| - | 減 | 求a減b的差 | a - b |
| * | 乘 | 可用于數字、序列等類型數據操作。對于數字類型是求積;其他類型是重復操作。 | a * b |
| / | 除 | 求a除以b的商 | a / b |
| % | 取余 | 求a除以b的余數 | a % b |
| ** | 冪 | 求a的b次冪 | a ** b |
| // | 地板除法 | 求小于a除以b商的最大整數 | a // b |
在Python Shell中運行示例代碼如下:
>>> 1 + 2 3 >>> 2 - 1 1 >>> 2 * 3 6 >>> 3 / 2 1.5 >>> 3 % 2 1 >>> 3 // 2 1 >>> -3 // 2 -2 >>> 10 ** 2 100 >>> 10.22 + 10 20.22 >>> 10.0 + True + 2 13.0上述例子中分別對數字類型數據進行了二元運算,其中True被當作整數1參與運算,操作數中有浮點數字,表達式計算結果也是浮點類型。其他代碼比較簡單不再贅述。
字符串屬于序列的一種,所以字符串可以使用+和*運算符,在Python
Shell中運行示例代碼如下:
+運算符會將兩個字符串連接起來,但不能將字符串與其他類型數據連接起來。*運算符第一操作數是字符串,第二操作數是整數,表示重復字符串多次。因此'Hello'
* 2結果是'HelloHello',注意第二操作數只能是整數。
關系運算符
關系運算是比較兩個表達式大小關系的運算,它的結果是布爾類型數據,即True或False。關系運算符有6種:==、!=、\>、\<、\>=和\<=,具體說明參見表7-2。
表 7?2 關系運算符
| == | 等于 | a等于b時返回True,否則返回False。 | a == b |
| != | 不等于 | 與==相反 | a != b |
| \>? | 大于 | a大于b時返回True,否則返回False | a \> b |
| \<? | 小于 | a小于b時返回True,否則返回False | a \< b |
| \>= | 大于等于 | a大于等于b時返回True,否則返回False | a \>= b |
| \<= | 小于等于 | a小于等于b時返回True,否則返回False | a \<= b |
在Python Shell中運行示例代碼如下:
>>> a = 1 >>> b = 2 >>> a > b False >>> a < b True >>> a >= b False >>> a <= b True >>> 1.0 == 1 True >>> 1.0 != 1 FalsePython中關系運算可用于比較序列或數字,整數、浮點數都是對象,可以使用關系運算符進行比較;字符串、列表和元組屬于序列也可以使用關系運算符進行比較。在Python Shell中運行示例代碼如下:
>>> a = 'Hello' >>> b = 'Hello' >>> a == b True >>> a = 'World' >>> a > b True >>> a < b False >>> a = [] ① >>> b = [1, 2] ② >>> a == b False >>> a < b True >>> a = [1, 2] >>> a == b True代碼第①行創建一個空列表,代碼第②行創建一個兩個元素的列表,他們也可以進行比較。
邏輯運算符
邏輯運算符是對布爾型變量進行運算,其結果也是布爾型,具體說明參見表7-3。
表 7?3 邏輯運算符
| not | 邏輯非 | a為True時,值為False,a為False時,值為True | not a |
| and | 邏輯與 | ab全為True時,計算結果為True,否則為False | a and b |
| or | 邏輯或 | ab全為False時,計算結果為False,否則為True | a or b |
Python中的“邏輯與”和“邏輯或”都采用“短路”設計,例如a and
b,如果a為True,則不計算b(因為不論 b為何值,“與”操作的結果都為False);而對于a
or b,如果a為True,則不計算b(因為不論b為何值,“或”操作的結果都為True)。
這種短路形式的設計,使他們在計算過程中就像電路短路一樣采用最優化的計算方式,從而提高效率。示例代碼如下:
# 代碼文件:chapter7/7.3/hello.pyi = 0 a = 10 b = 9if a > b or i == 1:print("或運算為 真") else:print("或運算為 假")if a < b and i == 1:print("與運算為 真") else:print("與運算為 假")def f1(): ①return a > bdef f2(): ②print('--f2--')return a == bprint(f1() or f2()) ③輸出結果如下:
或運算為 真 與運算為 假 True上述代碼第①行和第②行定義的兩個函數,函數返回的是布爾值。代碼第③行進行“或”運算,由于短路計算,f1函數返回True之后,f2函數不再調用。
位運算符
位運算是以二進位(bit)為單位進行運算的,操作數和結果都是整型數據。位運算符有如下幾個運算符:&、|、\^、\~、\>\>和\<\<,具體說明參見表7-4。
表 7?4 位運算符
| \~ | 位反 | \~x | 將x的值按位取反 |
| & | 位與 | x & y | x與y位進行位與運算 |
| | | 位或 | x | y | x與y位進行位或運算 |
| \^ | 位異或 | x \^ y | x與y位進行位異或運算 |
| \>\>? | 有符號右移 | x \>\> a | x右移a位,高位采用符號位補位 |
| \<\<? | 左移 | x \<\< a | x左移a位,低位用0補位 |
位運算示例代碼:
# 代碼文件:chapter7/7.4/hello.pya = 0b10110010 ① b = 0b01011110 ②print("a | b = {0}".format(a | b)) # 0b11111110 ③ print("a & b = {0}".format(a & b)) # 0b00010010 ④ print("a ^ b = {0}".format(a ^ b)) # 0b11101100 ⑤ print("~a = {0}".format(~a)) # -179 ⑥ print("a >> 2 = {0}".format(a >> 2)) # 0b00101100 ⑦ print("a << 2 = {0}".format(a << 2)) # 0b11001000 ⑧c = -0b1100 ⑨ print("c >> 2 = {0}".format(c >> 2)) # -0b00000011 ⑩ print("c << 2 = {0}".format(c << 2)) # -0b00110000 ?輸出結果如下:
a | b = 254 a & b = 18 a ^ b = 236 ~a = -179 a >> 2 = 44 a << 2 = 712 c >> 2 = -3 c << 2 = -48上述代碼中,在第①行和第②行分別聲明了整數變量a和b,采用二進制表示方式。第⑨行聲明變量c,采用二進制表示的負整數。
注意
a和b位數是與本機相關的,雖然只寫出了8位,但筆者計算機是64位的,所以a和b都是64位數字,只是在本例中省略了前56個零。位數的不這會影響位反和位移運算。
代碼第③行(a |
b)表達式是進行位或運算,結果是二進制的0b11111110(十進制是254),它的運算過程如圖7-1所示。從圖中可見,a和b按位進行或計算,只要有一個為1,這一位就為1,否則為0。
代碼第④行(a &
b)是進行位與運算,結果是二進制的0b00010010(十進制是18),它的運算過程如圖7-2所示。從圖中可見,a和b按位進行與計算,只有兩位全部為1,這一位才為1,否則為0。
代碼第⑤行(a \^
b)是進行位異或運算,結果是二進制的0b11101100(十進制是236),它的運算過程如圖7-3所示。從圖中可見,a和b按位進行異或計算,只有兩位相反時這一位才為1,否則為0。
代碼第⑥行(\~a)是按位取反運算,這個過程中需要補碼運算,而且與計算機位數有關。筆者使用的64位機,計算結果所是
-179。
代碼第⑦行(a \>\>
2)是進行右位移2位運算,結果是二進制的0b00101100(十進制是44),它的運算過程如圖7-4所示。從圖中可見,a的低位被移除掉,高位用0補位(注意最高為不是1,而是0,在1前面還有56個0)。
代碼第⑧行(a \<\<
2)是進行左位移2位運算,結果是二進制的0b1011001000(十進制是712),它的運算過程如圖7-5所示。從圖中可見,由于本機是64位,所以高位不會移除掉,低位用0補位。但是需要注意如果本機是8位的,高位會被移除掉,結果是二進制的0b11001000(十進制是310)。
提示
代碼第⑩行和第?行是對負數進行位運算,負數也涉及到補碼運算,如果對負數位移運算不理解可以先忽略負號當成正整數運行,然后運算出結果再加上負號。
提示 有符號右移n位,相當于操作數除以2n,例如代碼第⑦行(a \>\>
2)表達式相當于(a / 22), 178 /
4所以結果等于12。另外,左位移n位,相當于操作數乘以2n,例如代碼第⑩行(a \<\<
2)表達式相當于(a * 22),178 * 4所以結果等于712,類似的還有代碼第⑧行。
賦值運算符
賦值運算符只是一種簡寫,一般用于變量自身的變化,例如a與其操作數進行運算結果再賦值給a,算術運算符和位運算符中的二元運算符都有對應的賦值運算符。具體說明參見表7-5。
表 7?5 算術賦值運算符
| += | 加賦值 | a += b | 等價于a = a + b |
| -= | 減賦值 | a -= b | 等價于a = a - b |
| *= | 乘賦值 | a *= b | 等價于a = a * b |
| /= | 除賦值 | a /= b | 等價于a = a / b |
| %= | 取余賦值 | a %= b | 等價于a = a % b |
| **= | 冪賦值 | a **= b | 等價于a = a ** b |
| //= | 地板除法賦值 | a //= b | 等價于a = a // b |
| &= | 位與賦值 | a &= b | 等價于a = a&b |
| |= | 位或賦值 | a |= b | 等價于a = a|b |
| \^= | 位異或賦值 | a \^= b | 等價于a = a\^b |
| \<\<= | 左移賦值 | a \<\<= b | 等價于a = a\<\<b |
| \>\>= | 右移賦值 | a \>\>= b | 等價于a = a\>\>b |
示例代碼如下:
# 代碼文件:chapter7/7.5/hello.pya = 1 b = 2a += b # 相當于a = a + b print("a | b = {0}".format(a)) # 輸出結果3a += b + 3 # 相當于 a = a + b + 3 print("a + b + 3 = {0}".format(a)) # 輸出結果7 a -= b # 相當于a = a - b print("a - b = {0}".format(a)) # 輸出結果6a *= b # 相當于a = a * b print("a * b = {0}".format(a)) # 輸出結果12a /= b # 相當于a = a / b print("a / b = {0}".format(a)) # 輸出結果6a %= b # 相當于a = a % b print("a % b = {0}".format(a)) # 輸出結果0a = 0b10110010 b = 0b01011110a |= b print("a | b = {0}".format(a)) a ^= b print("a ^ b = {0}".format(a ^ b))輸出結果如下:
a | b = 3 a + b + 3 = 8 a - b = 6 a * b = 12 a / b = 6.0 a % b = 0.0 a | b = 254 a ^ b = 254上述例子分別對整型進行了賦值運算,具體語句不再贅述。
其他運算符
除了前面介紹的主要運算符,Python還有一些其他運算符,本節先介紹其中兩個“測試”相關重要的運算符,其他運算符會后面涉及到相關內容時再詳細介紹。這兩個“測試”運算符是:同一性測試運算符和成員測試運算符,所謂“測試”就是判斷之意,因此他們的運算結果是布爾值,他們也屬于關系運算符。
同一性測試運算符
同一性測試運算符就是測試兩個對象是否同一個對象,類似于==運算符,不同之處,==是測試兩個對象的內容是否相同,當然如果是同一對象==也返回True。
同一性測試運算符有兩個:is和is not,is是判斷是同一對象,is
not是判斷不是同一對象。示例代碼如下:
上述代碼第①行自定義類Person,它有兩個實例變量name和age,然后創建了兩個Person對象p1和p2,他們具有相同的name和age實例變量。那么是否可以說p1與p2是同一個對象(p1
is p2為True)?程序運行結果不是,因為這里實例化了兩個Person對象(Person('Tony',
18)語句是創建對象)。
那么p1 ==
p2為什么會返回False呢?因為==雖然是比較兩個對象的內容是否相當,但是也需要告訴對象比較的規則是什么,是比較name還是age?這需要在定義類時重寫eq方法,指定比較規則。修改代碼如下:
上述代碼重寫eq方法,其中定義了只有在name和age都同時相當時,兩個Person對象p1和p2才相等,即p1
== p2為True。注意p1 is
p2還是為False的。有關類和對象等細節問題讀者想必要關心,只需要知道is和==兩種運算符的不同即可。
成員測試運算符
成員測試運算符可以測試在一個序列(sequence)對象中是否包含某一個元素,成員測試運算符有兩個:in和not
in,in是測試是否包含某一個元素,not in是測試是否不包含某一個元素。
示例代碼如下:
# coding=utf-8 # 代碼文件:chapter7/7.6/ch7.6.2.pystring_a = 'Hello' print('e' in string_a) # True ① print('ell' not in string_a) # False ②list_a = [1, 2] print(2 in list_a) # True ③ print(1 not in list_a) # False ④上述代碼中第①行是判斷字符串Hello中是否包含e字符,第②行是判斷字符串Hello中是否不包含e字符串ell,這里需要注意的是字符串本質也屬于序列,此外還有列表和元組都屬于序列,有關序列的知識會在第9章詳細介紹。
代碼第③行是判斷list_a 列表中是否包含2元素,代碼第④行是判斷list_a
列表中是否不包含1元素。
運算符優先級
在一個表達式計算過程中,運算符的優先級非常重要。表7-6中從上到下優先級從高到低,同一行具有相同的優先級。
表 7?6運算符優先級
| 1 | () | 小括號 |
| 2 | f(參數) | 函數調用 |
| 3 | [start:end], [start:end:step] | 分片 |
| 4 | [index] | 下標 |
| 5 | . | 引用類成員 |
| 6 | ** | 冪 |
| 7 | \~ | 位反 |
| 8 | +, - | 正負號 |
| 9 | *, /, % | 乘法、除法、取余 |
| 10 | +, - | 加法、減法 |
| 11 | \<\<, \>\> | 位移 |
| 12 | & | 位與 |
| 13 | \^ | 位異或 |
| 14 | | | 位或 |
| 15 | in, not in, is, is not, \<, \<=,? \>,? \>=,\<\>, !=, == | 比較 |
| 16 | not | 邏輯非 |
| 17 | and | 邏輯與 |
| 18 | or | 邏輯或 |
| 19 | lambda | Lambda表達式 |
通過表7-6所示讀者對運算符優先級有一個大體上了解,知道運算符優先級大體順序從高到低是:算術運算符→位運算符→關系運算符→邏輯運算符→賦值運算符。還有一些運算符還沒有介紹,會在后面的逐一介紹。
本章小結
通過對本章內容的學習,讀者可以了解到Python語言運算符,這些運算符包括:算術運算符、關系運算符、邏輯運算符、位運算符和其他運算符。最后介紹了Python運算符優先級。
配套視頻
http://edu.51cto.com/sd/f907b
配套源代碼
http://www.zhijieketang.com/group/8
電子書
https://yuedu.baidu.com/ebook/5823871e59fafab069dc5022aaea998fcc2240fc
作者微博:@tony_關東升br/>郵箱:eorient@sina.com
智捷課堂微信公共號:zhijieketang
Python讀者服務QQ群:628808216
總結
以上是生活随笔為你收集整理的《Python从小白到大牛》第7章 运算符的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: redux-form(V7.4.2)笔记
- 下一篇: 点击一百万次(详解)——bugku