1. 程式人生 > 其它 >Python序列的增量賦值

Python序列的增量賦值

技術標籤:程式語言python

增量賦值運算子有 += 和 *=。+= 背後的特殊方法是 __iadd__,如果一個類沒有實現__iadd__方法,Python 會退一步呼叫__add__方法。這兩個方法的區別在於,__iadd__為就地改動,不會改變原值的記憶體地址,而 __add__ 方法會得到一個新物件。

考慮下面一個表示式:

a += b

如果 a 實現了__iadd__ 方法,a 會就地改動(記憶體地址不變)。如果 a 沒有實現 __iadd__ 方法,那麼 a += b這個表示式的效果就變得跟a = a + b一樣了,生成一個新的物件賦給 a。

總體來講,可變序列一般都實現了 __iadd__

方法,因此 += 是就地加法,而不可變序列根本就不支援這個操作。

*=+= 一樣,只是背後的特殊方法為__imul__

'''
遇到問題沒人解答?小編建立了一個Python學習交流QQ群:778463939
尋找有志同道合的小夥伴,互幫互助,群裡還有不錯的視訊學習教程和PDF電子書!
'''
a = [1, 2, 3]
b = [4, 5, 6]
print("id(a) = %d" % id(a))
a += b
print("id(a) = %d" % id(a))

c = [1, 2, 3]
print("id(c) = %d"
% id(c)) c = c + b print("id(c) = %d" % id(c)) d = (1, 2, 3) print("id(d) = %d" % id(d)) d *= 2 print("id(d) = %d" % id(d))

執行結果如下:

id(a) = 1298277978824
id(a) = 1298277978824
id(c) = 1298277978696
id(c) = 1298277978632
id(d) = 1298277972872
id(d) = 1298277136616

瞭解了序列的增量賦值,我們來看 Leonardo Rochael 在 2013 年的 Python 巴西會議上提到的謎題:

t = (1, 2, [30, 40])
t[2] += [50, 60]

A. t 變成 (1, 2, [30, 40, 50, 60])

B. 因為 tuple 不支援對它的元素賦值,所以會丟擲 TypeError 異常

C. 以上兩個都不是

D. A 和 B 都是對的

估計很多人會跟我一樣選 B,但其實答案是 D。在控制檯執行程式碼,顯示結果如下:
在這裡插入圖片描述
總結:

1、對不可變序列進行重複拼接操作的話,效率會很低,因為每次都要新建一個序列,然後把原來序列中的元素複製到新的序列裡,然後再追加新的元素。

2、不要把可變物件放在元組裡面。

3、增量賦值不是一個原子操作,我們剛才也看到了,它雖然丟擲了異常,但 t 的值還是改變了。