[Python] list vs tupple

leetao94發表於2020-07-04

前言

列表(list)和 元組(tupple) 是 Python 中常見的兩種資料結構.這兩者使用方法有一定的相似,倆者都是 Python 內建型別,都可以儲存資料集合,都可以儲存複合資料,我們同樣可以通過索引去訪問它們.

那麼問題來了,倆者究竟有區別嗎???

list 和 tupple 的區別

首先回答問題.list 和 tupple 有區別嗎?答案是肯定的,兩者有區別. list 和 tupple 的本質區別在於,前者是一個可變物件而後者是一個不可變物件。

什麼是可變物件和不可變物件呢?簡單地來說,可變物件就是建立之後可以修改,而不可變物件則是建立之後不允許在修改。

沒關係,讓我們看一下例子

首先建立一個 list

>>> a = ["a","b","c","d"]

接著我們試著修改一下上面的 list , 將 b 改成 e,看看會發生什麼

>>> a[1] = "e"
>>> a
['a', 'e', 'c', 'd']

好像什麼都沒有發生~~

沒關係,我們再來建立一個 tupple

>>> b=("a","b","c","d")

同樣地,讓我們將 tupple 中的 b 改成 e

>>> b[1]="2"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

為什麼同樣的賦值操作,在 tupple 中會出現錯誤呢?原因就是我們上面說到的 tupple 是不可變物件,建立之後不能修改

有個小夥伴看見了

然後給我寫了一段下面的程式碼

>>> b=("a","b","c","d")
>>> b=("a","e","c","d")
>>>b
>>>("a","e","c","d")

這樣子是不是做到了修改 tupple 中的第2個元素呢?答案是否定的,為什麼呢?彆著急往下看

可變物件和不可變物件

在開始下面的內容之前,需要牢記一句話,Python 中的變數是對在記憶體中 Python 物件的引用

以我們上面的列表 a 為例

>>> a = ["a","b","c","d"]

它在記憶體中實際表現如下圖

如果需要獲取列表 list 在記憶體的實際位置,我們可以借用內建函式 id()

>>> a=["a","b","c","d"]
>>> id(a)
4557552456

現在我們去修改一下 a[1] 的值,然後再用 id() 這個函式去獲取 a 在記憶體的地址,你會發現它的值沒有改變,仍然指向相同位置

>>> a[1] = "e"
>>> id(a)
4557552456

整個過程如下圖

接下來我們看一下對 tupple 進行同樣的操作會有什麼變化

>>> a=("a","b","c","d")
>>> id(a)
4557412296
>>> a=("a","e","c","d")
>>> id(a)
4557586504

不難發現,再修改之後指向記憶體中的地址發生了改變,這意味著這個時候變數 a 指向了一個全新的物件。

如果覺得難以理解,沒有關係,看下面的圖

這個時候如果沒有其它變數指向之前的 tupple,Python 的 GC 將會把舊的 tupple 從記憶體中完全刪除.

為什麼需要 list 和 tupple ?

其實更貼切的應該問,為什麼需要可變物件和不可變物件呢?

  1. 新增元素效率

從上面的內容,我們知道一旦建立了 tupple,這個時候任何修改操作都會去建立新的物件,然後變數重新指向新的物件,假設新增的元素足夠多,其效率可想而知。這裡的新增是指如下的操作( tupple 本身沒有新增的方法)

a = ()
for i in range(num):
    a = a + (i,)
  1. debugger 難度

在之前的 [直接賦值,深拷貝和淺拷貝] 中提到可變物件,修改賦值後的變數,會對原有的變數造成影響,會導致其 value 值的改變,在實際開發過程中很容易被忽略

>>> a = [1, 3, 5, 7]
>>> b = a
>>> b[0] = -10
>>> a
[-10, 3, 5, 7]

什麼時候去使用 tupple 和 list

總結一下,list 和 tupple 的使用場景

  1. tupple 不存在新增和刪除的操作,更不存在修改的操作,如果有這些需求,不用使用 tupple,去用 list
  2. 如果只是遍歷的話, tupple 的速度是比 list 要快的
  3. 如果你有些資料是需要防寫,不希望在執行過程中被修改的話,用 tupple
  4. tupple 可以用來做 dict 的 key 的,準確的說,所有不可變物件都可以,而 list 不可以

參考

https://learnbatta.com/blog/why-tuple-is-faster-than-list-in-python-22/

https://www.afternerd.com/blog/difference-between-list-tuple/

https://www.programiz.com/python-programming/list-vs-tuples

相關文章