瘋狂的元組
你好,我是征哥,今天分享一道 Python 題目,可能會讓你漲點知識。
題目:以下代碼的輸出結(jié)果是什么?
>>>?crazy_tuple?=?(["x","y"],)
>>>?crazy_tuple[0]?=?crazy_tuple[0].__iadd__(["z"])
>>>?print(crazy_tuple[0])
???
選項:
A) ["x", "y"] B) ["x", "y", "z"] C) 會拋出 TypeError 異常 D) 有沒有搞錯?
先鋪墊一個小知識,列表的魔法函數(shù) __iadd__ 相當于列表的 extend 函數(shù),但是會返回擴展后的結(jié)果:
>>>?[1,2,3].__iadd__([4])
[1,?2,?3,?4]
接下來你會選擇哪個選項呢?
等你 30 秒。
接下來在 Python 解釋器上運行一下,看看是否符合你的預(yù)期:
>>>?crazy_tuple?=?(["x","y"],)
>>>?crazy_tuple[0]?=?crazy_tuple[0].__iadd__(["z"])
Traceback?(most?recent?call?last):
??File?"" ,?line?1,?in?
TypeError:?'tuple'?object?does?not?support?item?assignment
>>>?print(crazy_tuple[0])
['x',?'y',?'z']
>>>
會發(fā)現(xiàn),第二行代碼拋出了 TypeError 異常,告訴我們,元組不支持元素賦值,此時,你會選擇 C,但是打印第一個元素(列表)時發(fā)現(xiàn)列表添加了 'z',你又選擇了 B。
你又想了想,Python 是不是搞錯了,既然你不支持元組內(nèi)的元素重新賦值,還讓它賦值了,是不是搞錯了,你想選擇 D。
所以這很 crazy !
現(xiàn)在來一起梳理一下。
首先,crazy_tuple 是一個元組,元組不可變,是指元組內(nèi)元素的地址永不改變:
>>>?crazy_tuple?=?(["x","y"],)
>>>?id(crazy_tuple[0])
140468737595456
凡是對列表內(nèi)的元素使用 = 操作符號的,均拋出 TypeError 異常
>>>?id(crazy_tuple[0])
140468737595456
>>>?crazy_tuple[0]?=?object()
Traceback?(most?recent?call?last):
??File?"" ,?line?1,?in?
TypeError:?'tuple'?object?does?not?support?item?assignment
>>>?id(crazy_tuple[0])
140468737595456
>>>?crazy_tuple[0]
['x',?'y']
>>>
雖然拋出了異常,但是地址仍然不變。
我們執(zhí)行的代碼是 crazy_tuple[0] = crazy_tuple[0].__iadd__(["z"]),Python 解釋器先執(zhí)行的是等號右邊的部分 crazy_tuple[0].__iadd__(["z"])
我們可以這樣分解它的執(zhí)行過程:
tmp?=?crazy_tuple[0].__iadd__(["z"])
crazy_tuple[0]?=?tmp
在解釋器執(zhí)行一下:
>>>?tmp?=?crazy_tuple[0].__iadd__(["z"])
>>>?crazy_tuple[0]
['x',?'y',?'z']
>>>?id(crazy_tuple[0])
140468737595456
>>>?crazy_tuple[0]?=?tmp
Traceback?(most?recent?call?last):
??File?"" ,?line?1,?in?
TypeError:?'tuple'?object?does?not?support?item?assignment
>>>
tmp?=?crazy_tuple[0].__iadd__(["z"])
crazy_tuple[0]?=?tmp?
可以看出, crazy_tuple[0].__iadd__(["z"]) 執(zhí)行之后,crazy_tuple[0] 的內(nèi)容已經(jīng)發(fā)生了變化,但地址不變。
因此,你雖然看到了報錯,但是修改的結(jié)果還是發(fā)生了。
總結(jié):元組的不可變,在于元組內(nèi)元素的地址不可變。如果元組內(nèi)元素是字符串、數(shù)字、元組等不可變對象,其內(nèi)容永久不變,如果元組內(nèi)元素是是列表、字典、集合等可變對象,其內(nèi)容可以被改變。具體可參考前文Python 基礎(chǔ)系列--可變/不可變的數(shù)據(jù)類型
最后的話
本文分享了一道有趣的 Python 題目,希望對你對 Python 編程有所思考。獨學(xué)而無友,則孤陋而寡聞,因此我組建了一個純技術(shù)交流群,關(guān)注公眾號「Python七號」回復(fù)「入群」加入技術(shù)交流群。有問題,可以留言討論。
