列表切片賦值給另一個變數

darklight發表於2019-09-19

今天本想考查一下list切片的問題,但沒想到差點把自己坑了。

我把a的一段切片賦值給了b,然後看了一下它們的地址。

再重新做一遍相同的賦值操作,結果a的切片地址和b的地址交換了。

>>> 
>>> a = [1,2,3,4,5]    # 建立列表a
>>> b = a[1:3]         # 把a的一段切片賦值給b
>>> 
>>> 
>>> id(b)              # 檢視b的地址
139825038891208
>>> 
>>> id(a[1:3])         # 檢視a切片的地址
139824894069256
>>> 
>>> 
>>> b = a[1:3]         # 再一次把a切片賦值給b
>>> 
>>> id(b)              # b的地址變成了之前a切片的地址
139824894069256
>>> 
>>> id(a[1:3])         # a切片的地址變成了之前b的地址
139825038891208
>>> 

我一時沒有反應過來,難道把一段切片賦值給另一個變數會導致它們的地址交換?

後來想明白了,做了下面的測試。

>>> 
>>> id(b)            # 檢視b的地址
139824894069256
>>> 
>>> id(a[1:3])       # 檢視a切片的地址
139824894069832
>>> 
>>> b = a[1:3]       # 把a切片賦值給b
>>> 
>>> id(b)            # b的地址變成了之前a切片的地址
139824894069832
>>> 
>>> f = [6,7]        # 新建立一個列表f
>>> 
>>> id(f)            # 此時f的地址變成了之前b的地址
139824894069256
>>> 
>>> id(a[1:3])       # a切片的地址是一個新地址
139824894069640
>>>

在把a的切片賦值給b之後,如果又新建一個列表f,這個f的地址就變成原來b的地址了。

原因:

實際上訪問a切片時生成了一個新的列表,把它賦值給b,那麼b的地址就變成了這個新列表的地址,而b原來的地址自然就釋放了。

這個時候如果再訪問一次a的切片,那麼它又新生成一個列表,這個新生成的列表就剛好把原來b釋放的地址使用了。

如果此時不是訪問a的切片而是新建一個列表f,那麼這個f就會把原來b的地址用掉。在這之後再訪問a的切片,那麼它新生成的列表使用的就是另外一個新的地址了。

所以不存在什麼地址交換,只是一個又一個的列表生成、釋放而已。

相關文章