跳轉到內容

Python 程式設計/運算子

來自 Wikibooks,開放世界中的開放書籍


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

連結

模運算

[編輯 | 編輯原始碼]

模運算(兩個運算元除法的餘數,而不是商)可以使用 % 運算子找到,或者使用 divmod 內建函式找到。divmod 函式返回一個包含商和餘數的元組

>>> 10 % 7
3
>>> -10 % 7
4

請注意,-10 % 7 等於 +4,而在 C 語言中它等於 -3。這是因為 Python 向負無窮大取整而不是零。因此,餘數向正無窮大增加。因此,由於 -10 / 7 = -1.4286 被向下取整為 -2.0,所以餘數變為 x,使得 -14 + x = -10。

連結

與某些其他語言不同,變數可以直接取反

>>> x = 5
>>> -x
-5

比較運算

[編輯 | 編輯原始碼]
運算子 含義
< 小於
> 大於
<= 小於等於
>= 大於等於
== 等於
!= 不等於

數字、字串和其他型別可以比較相等/不相等和排序

>>> 2 == 3
False
>>> 3 == 3
True
>>> 3 == '3'
False
>>> 2 < 3
True
>>> "a" < "aa"
True

身份運算

[編輯 | 編輯原始碼]

運算子 isis 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

連結

增強賦值

[編輯 | 編輯原始碼]

有一種簡寫方法可以將操作的結果賦值給其中一個輸入

>>> 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

與 (and)

[編輯 | 編輯原始碼]

與運算子只有在所有布林值都為真時才返回真。如果任何一個為假,則與運算子返回假。

if a and b:
    do_this
else:
    do_this

非 (not)

[編輯 | 編輯原始碼]

非運算子只作用於一個布林值,並簡單地返回其相反值。因此,真變為假,假變為真。

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 的連結中顯示。

連結

參考文獻

[編輯 | 編輯原始碼]
[編輯 | 編輯原始碼]
華夏公益教科書