1. 程式人生 > >Python 進階 —— x = x+1 vs x += 1

Python 進階 —— x = x+1 vs x += 1

0. 可變物件,不可變物件

  • list 是可變物件:

  • tuple,int 等是不可變物件

  • += 會首先呼叫物件的 .__iadd__方法,對物件本身進行修改,無返回值;如果物件為不可變物件,則會繼續呼叫其 .__add__方法,返回操作後的結果;

    • __iadd__ in dir(tuple) ⇒ False
    • __iadd__ in dir(list) ⇒ True
    • __iadd__ in dir(int) ⇒ False
  • 對於不可變物件 a(如 tuple 或 int),a += b 與 a = a + b 等價;

    >> x = (1, 2)
    >> id(x)
    4460706120
    >> x += (3, )
    (1, 2, 3)
    >> x
    >> id(x)
    4438616104
    

1. 舉例

  • x += 1:in-place(就地)修改 x 自身的值,前提 x 必須是可變物件;

  • x = x + 1

    會隱式地建立一個新的物件,表示 x 與 1的和,同時用同樣的 name 指向它,所以它的含義和y = x+1相同,只不過這裡將y取名為x罷了;

當我們用多個變數名指向同一物件實體時,可能對比會更加明顯:

>> y = x = []
>> x += [5]
>> x
[5]
>> y 
[5]

>> x = x + [5]
>> x
[5, 5]
>> y
[5]

以下是關於 +

+=運算子過載(magic method)的說明

  • +:呼叫 __add__,不修改它的兩個運算元
  • +=:呼叫__iadd__,會修改它自身的值

注:表示式本身是沒有返回值的,如x = 1,甚至不會返回 None,y = x = 1含義不是y = (x = 1),而是 yx 指向相同的1所在的記憶體物件。

如此我們也可理解 Python 下簡潔的 swap:

x, y = y, x

是將 x 指向 原始的 y,y 指向 原始的 x,也即可簡單理解為同時發生,而不是:

x = y
y = x
			# 走的就是C/C++ swap 的老路了
			# 需要藉助中間變數

references

[1] <a href=“http://stackoverflow.com/questions/12905338/python-difference-between-x-x1-and-x-1/12905374”, target="_blank">Python Difference between x = x+1 and x += 1