Python 程式設計/運算子
Python 數學運算按預期工作
>>> x = 2
>>> y = 3
>>> z = 5
>>> x * y
6
>>> x + y
5
>>> y - x
1
>>> x * y + z
11
>>> (x + y) * z
25
>>> 3.0 / 2.0 # True division
1.5
>>> 3 // 2 # Floor division
1
>>> 2 ** 3 # Exponentiation
8
請注意,Python 遵循運算子優先順序。
Python 內建了冪運算子 **,它可以作用於整數、浮點數或複數。它在運算子優先順序中佔據其適當的位置。
>>> 2**8
256
在 Python 3.x 中,斜槓運算子 ("/") 對所有型別(包括整數)執行真除,因此,例如 3/2==1.5[1][2]。即使兩個輸入都是整數,結果也是浮點型別:4 / 2 的結果是 2.0。
在 Python 3.x 和最新的 2.x 中,整數引數和浮點數引數的地板除是透過使用雙斜槓 ("//") 運算子實現的。對於負結果,這與 C 語言中的整數除法不同,因為在 Python 中 -3 // 2 == -2,而在 C 中 -3 / 2 == -1:C 將負結果舍入到零,而 Python 舍入到負無窮大。
請注意,由於浮點數運算的限制,舍入誤差可能導致意外結果。例如
>>> print(0.6/0.2) 3.0 >>> print(0.6//0.2) 2.0
對於 Python 2.x,使用斜槓運算子 ("/") 對兩個整數或長整數進行除法時,使用地板除(在除法後應用向下取整函式),併產生一個整數或長整數。因此,5 / 2 == 2 且 -3 / 2 == -2。以這種方式使用 "/" 進行除法已棄用;如果您想要地板除,請使用 "//"(在 Python 2.2 及更高版本中可用)。除以或除以浮點數將導致 Python 使用真除。因此,為了確保在 Python 2.x 中進行真除:x=3; y=2; float(x)/y == 1.5。
連結
- 6.7. 二元算術運算,在 Python 語言參考,docs.python.org
- Python 風格的整數除法和模運算在 C 中,stackoverflow.com
- C++ 中負數的整數除法舍入,stackoverflow.com
- 在 Python 中,在整數除法中向零舍入的良好方法是什麼?,stackoverflow.com
- 為什麼 Python 的整數除法向下取整,python-history.blogspot.com
模運算(兩個運算元除法的餘數,而不是商)可以使用 % 運算子找到,或者使用 divmod 內建函式找到。divmod 函式返回一個包含商和餘數的元組。
>>> 10 % 7
3
>>> -10 % 7
4
請注意,-10 % 7 等於 +4,而在 C 語言中它等於 -3。這是因為 Python 向負無窮大取整而不是零。因此,餘數向正無窮大增加。因此,由於 -10 / 7 = -1.4286 被向下取整為 -2.0,所以餘數變為 x,使得 -14 + x = -10。
連結
- 6.7. 二元算術運算,在 Python 語言參考,docs.python.org
與某些其他語言不同,變數可以直接取反
>>> x = 5
>>> -x
-5
| 運算子 | 含義 |
|---|---|
| < | 小於 |
| > | 大於 |
| <= | 小於等於 |
| >= | 大於等於 |
| == | 等於 |
| != | 不等於 |
數字、字串和其他型別可以比較相等/不相等和排序
>>> 2 == 3
False
>>> 3 == 3
True
>>> 3 == '3'
False
>>> 2 < 3
True
>>> "a" < "aa"
True
運算子 is 和 is not 用於測試物件身份,並與 ==(等於)形成對比:x is y 當且僅當 x 和 y 是記憶體中同一個物件的引用時才為真。x is not y 產生相反的真值。請注意,身份測試比相等測試更嚴格,因為兩個不同的物件可能具有相同的值。
>>> [1,2,3] == [1,2,3]
True
>>> [1,2,3] is [1,2,3]
False
對於內建的不可變資料型別(如 int、str 和 tuple),Python 使用快取機制來提高效能,即直譯器可能會決定重用現有的不可變物件,而不是生成一個具有相同值的新的物件。物件快取的細節在不同的 Python 版本之間可能會發生變化,並且不保證是系統無關的,因此對不可變物件的標識檢查,例如 'hello' is 'hello'、(1,2,3) is (1,2,3)、4 is 2**2 在不同的機器上可能產生不同的結果。
在某些 Python 實現中,以下結果適用
print(8 is 8) # True
print("str" is "str") # True
print((1, 2) is (1, 2)) # False - whyever, it is immutable
print([1, 2] is [1, 2]) # False
print(id(8) == id(8)) # True
int1 = 8
print(int1 is 8) # True
oldid = id(int1)
int1 += 2
print(id(int1) == oldid)# False
連結
- 3. 資料模型,python.org
- 2. 內建函式 # id,python.org
- 5. 表示式 # is,python.org
有一種簡寫方法可以將操作的結果賦值給其中一個輸入
>>> x = 2
>>> x # 2
2
>>> x *= 3
>>> x # 2 * 3
6
>>> x += 4
>>> x # 2 * 3 + 4
10
>>> x /= 5
>>> x # (2 * 3 + 4) / 5
2
>>> x **= 2
>>> x # ((2 * 3 + 4) / 5) ** 2
4
>>> x %= 3
>>> x # ((2 * 3 + 4) / 5) ** 2 % 3
1
>>> x = 'repeat this '
>>> x # repeat this
repeat this
>>> x *= 3 # fill with x repeated three times
>>> x
repeat this repeat this repeat this
邏輯運算子是作用於布林值的運算子。
或運算子如果任何一個布林值為真則返回真。如果它們都不為真(換句話說,它們都為假),則或運算子返回假。
if a or b:
do_this
else:
do_this
與運算子只有在所有布林值都為真時才返回真。如果任何一個為假,則與運算子返回假。
if a and b:
do_this
else:
do_this
非運算子只作用於一個布林值,並簡單地返回其相反值。因此,真變為假,假變為真。
if not a:
do_this
else:
do_this
這裡的運算子優先順序是:非優先,與其次,或最後。特別是,“True or True and False or False”變為“True or False or False”,結果為 True。
警告,邏輯運算子可以作用於布林值以外的事物。例如,“1 and 6”將返回 6。具體來說,“and”返回第一個被認為是假的的值,或者如果所有值都被認為是真則返回最後一個值。“or”返回第一個真值,或者如果所有值都被認為是假則返回最後一個值。在 Python 中,數字 零 和空字串、列表、集合等被認為是假。您可以使用 bool() 檢查 Python 中某物是否被認為是真或假。例如,bool(0.0) 和 bool([]) 都返回 False。
Python 中用於位運算的運算子與 C 語言中的類似。它們包括 &(按位與)、|(按位或)、^(異或)、<<(左移)、>>(右移)和 ~(取反)。位運算的增強賦值運算子(也稱為複合賦值運算子)包括 &=、|=、^=、<<= 和 >>=。位運算子適用於整數,包括負數和非常大的整數;對於移位運算子,第二個運算元必須是非負數。在 Python 內部幫助中,這在 EXPRESSIONS 和 BITWISE 主題下有介紹。
示例
- 0b1101 & 0b111 == 0b101
- 注意:0b 開頭表示二進位制字面量,就像 0x 開頭表示十六進位制字面量一樣。
- 0b1 | 0b100 == 0b101
- 0b111 ^ 0b101 == 0b10
- 1 << 4 == 16
- 7 >> 1 == 3
- 1 << 100 == 0x10000000000000000000000000
- 支援較大的結果。
- 1 << -1
- 錯誤:第二個運算元必須是非負數。
- -2 & 15 == 14
- 對於位運算,負整數被視為使用補碼錶示,並在前面有無限個 1。因此,-2 就如同 0x...FFFFFFFFFE,將其與 15 (0xF) 進行按位與運算,結果為 0xE,即 14。
- format(-2 % (1 << 32), "032b")
- 確定一個字串,顯示 -2 的隱式補碼錶示的最後 32 位。
- ~-2 == 1
- 上述關於負整數處理的說明適用。對於取反 (~),這種處理方式得到 ~x == -1 * (x + 1)。可以驗證:min((~x == -1 * (x + 1) for x in range(-10 ** 6, 10 ** 6))) == True。
- ~1 == -2
- 上面提到的公式 ~x == -1 * (x + 1) 適用。在按位取反的解釋中,1 的所有虛假前導零都被翻轉為前導一,然後被解釋為 -2 的補碼錶示,就如同 0x...FFFFFFFFFE。
- x = 0b11110101; x &= ~(0xF << 1); x == 0b11100001
- 一個常見的習慣用法是使用取反來清除最低有效位 5 到 2,這顯示了負數的無限前導一的補碼隱式表示在位運算中的實用性。適用於任意大的 x。
- ~2 & 0xFFFFFFFF == 0xFFFFFFFD
- 我們可以透過將取反的結果與最大無符號 32 位整數 0xFFFFFFFF 進行按位與運算,來模擬 32 位整數的按位取反。對於 8 位取反、16 位取反等,我們可以透過將取反的結果與 0xFF、0xFFFF 等進行按位與運算來進行類似的操作。
- 2 ^ 0xFFFFFFFF == 0xFFFFFFFD
- 模擬固定大小的按位取反的另一種方法是,與該大小的所有 F 進行異或運算。
- v = 2.0 & 2
- 產生錯誤:沒有自動將浮點數轉換為整數,也沒有對浮點數的底層表示進行運算。
- int.bit_length(0x8000) == 16
- 確定表示該整數所需的位數。因此,min((int.bit_length(1 << x) == x + 1 for x in range(100000))) == True。
增強賦值運算子的示例
- a = 0b1101; a &= 0b111; a == 0b101
- a = 0b1; a |= 0b100; a == 0b101
- a = 0b111; a ^= 0b101; a == 0b10
- a = 1; a <<= 4; a == 16
- a = 7; a >>= 1; a == 3
類定義可以過載類的例項的運算子;因此,例如,集合過載了管道 (|) 運算子,表示集合並集:{1,2} | {3,4} == {1,2,3,4}。過載方法的名稱為 __and__ 用於 &、__or__ 用於 |、__xor__ 用於 ^、__invert__ 用於 ~、__lshift__ 用於 <<、__rshift__ 用於 >>、__iand__ 用於 &=、__ior__ 用於 |=、__ixor__ 用於 ^=、__ilshift__ 用於 <<= 和 __irshift__ 用於 >>=。
位運算的應用示例包括 CRC 和 MD5 的計算。誠然,為了獲得最大的速度,這些通常會在 C 而不是 Python 中實現;實際上,Python 有用 C 編寫的這些庫。儘管如此,在 Python 中實現也是可能的,並在下面指向 Rosetta Code 的連結中顯示。
連結
- 位運算子,wiki.python.org
- 位操作,wiki.python.org
- 整數型別的位運算 在庫參考中,docs.python.org
- 2.5. 運算子 在 Python 語言參考中,docs.python.org
- 6. 表示式 在 Python 語言參考中,docs.python.org
- 3. 資料模型 在 Python 語言參考中,docs.python.org
- "整數 (int) [...] 為了移位和掩碼操作的目的,假設使用二進位制表示,負數使用 2 的補碼的變體表示,這使得看起來好像有一個無限的符號位字串向左延伸。"
- 按位運算,wikipedia.org
- C 語言中的按位運算,wikipedia.org
- PEP 203 – 增強賦值,python.org
- 按位運算及其用法,stackoverflow.com
- CRC-32 # Python,rosettacode.org
- MD5/實現 # Python,rosettacode.org
- longobject.c 在 python/cpython 中,github.com - 函式 long_bitwise、long_rshift、long_lshift 和 long_invert