《Python從小白到大牛》第7章 運算符

《Python從小白到大牛》已經上市!
《Python從小白到大牛》第7章 運算符
本章爲大家介紹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' + 'World'
'HelloWorld'
>>> 'Hello' + 2
Traceback (most recent call last):
  File "<pyshell#35>", line 1, in <module>
    'Hello' + 2
TypeError: must be str, not int
>>>
>>> 'Hello' * 2
'HelloHello'
>>> 'Hello' * 2.2
Traceback (most recent call last):
  File "<pyshell#36>", line 1, in <module>
    'Hello' * 2.2
TypeError: can't multiply sequence by non-int of type 'float'

+運算符會將兩個字符串連接起來,但不能將字符串與其他類型數據連接起來。*運算符第一操作數是字符串,第二操作數是整數,表示重複字符串多次。因此'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
False

Python中關係運算可用於比較序列或數字,整數、浮點數都是對象,可以使用關係運算符進行比較;字符串、列表和元組屬於序列也可以使用關係運算符進行比較。在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.py

i = 0
a = 10
b = 9

if a > b or i == 1:
    print("或運算爲 真")
else:
    print("或運算爲 假")

if a < b and i == 1:
    print("與運算爲 真")
else:
    print("與運算爲 假")

def f1():   ①
    return a > b

def f2():   ②
    print('--f2--')
    return a == b

print(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.py

a = 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。

圖7-1 位或運算

代碼第④行(a &
b)是進行位與運算,結果是二進制的0b00010010(十進制是18),它的運算過程如圖7-2所示。從圖中可見,a和b按位進行與計算,只有兩位全部爲1,這一位才爲1,否則爲0。

圖7-2 位與運算

代碼第⑤行(a \^
b)是進行位異或運算,結果是二進制的0b11101100(十進制是236),它的運算過程如圖7-3所示。從圖中可見,a和b按位進行異或計算,只有兩位相反時這一位才爲1,否則爲0。

圖7-3 異或位運算

代碼第⑥行(\~a)是按位取反運算,這個過程中需要補碼運算,而且與計算機位數有關。筆者使用的64位機,計算結果所是
-179。

代碼第⑦行(a \>\>
2)是進行右位移2位運算,結果是二進制的0b00101100(十進制是44),它的運算過程如圖7-4所示。從圖中可見,a的低位被移除掉,高位用0補位(注意最高爲不是1,而是0,在1前面還有56個0)。

圖7-4 右位移2位運算

代碼第⑧行(a \<\<
2)是進行左位移2位運算,結果是二進制的0b1011001000(十進制是712),它的運算過程如圖7-5所示。從圖中可見,由於本機是64位,所以高位不會移除掉,低位用0補位。但是需要注意如果本機是8位的,高位會被移除掉,結果是二進制的0b11001000(十進制是310)。

圖7-5 左位移2位運算

提示
代碼第⑩行和第⑪行是對負數進行位運算,負數也涉及到補碼運算,如果對負數位移運算不理解可以先忽略負號當成正整數運行,然後運算出結果再加上負號。

提示 有符號右移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.py

a = 1
b = 2

a += b  # 相當於a = a + b
print("a | b = {0}".format(a))  # 輸出結果3

a += 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))  # 輸出結果6

a *= b  # 相當於a = a * b
print("a * b = {0}".format(a))  # 輸出結果12

a /= b  # 相當於a = a / b
print("a / b = {0}".format(a))  # 輸出結果6

a %= b  # 相當於a = a % b
print("a % b = {0}".format(a))  # 輸出結果0

a = 0b10110010
b = 0b01011110

a |= 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是判斷不是同一對象。示例代碼如下:

# coding=utf-8
# 代碼文件:chapter7/7.6/ch7.6.1.py

class Person:       ①
    def __init__(self, name, age):
        self.name = name
        self.age = age

p1 = Person('Tony', 18)     
p2 = Person('Tony', 18)

print(p1 == p2)  # False    
print(p1 is p2)  # False

print(p1 != p2)  # True
print(p1 is not p2)  # True

上述代碼第①行自定義類Person,它有兩個實例變量name和age,然後創建了兩個Person對象p1和p2,他們具有相同的name和age實例變量。那麼是否可以說p1與p2是同一個對象(p1
is p2爲True)?程序運行結果不是,因爲這裏實例化了兩個Person對象(Person('Tony',
18)語句是創建對象)。

那麼p1 ==
p2爲什麼會返回False呢?因爲==雖然是比較兩個對象的內容是否相當,但是也需要告訴對象比較的規則是什麼,是比較name還是age?這需要在定義類時重寫eq方法,指定比較規則。修改代碼如下:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __eq__(self, other):
        if self.name == other.name and self.age == other.age:
            return True
        else:
            return False

p1 = Person('Tony', 18)
p2 = Person('Tony', 18)

print(p1 == p2)  # True
print(p1 is p2)  # False

print(p1 != p2)  # False
print(p1 is not p2)  # True

上述代碼重寫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.py

string_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/>郵箱:[email protected]
智捷課堂微信公共號:zhijieketang
Python讀者服務QQ羣:628808216

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