前言
列表(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 ?
其實更貼切的應該問,為什麼需要可變物件和不可變物件呢?
- 新增元素效率
從上面的內容,我們知道一旦建立了 tupple,這個時候任何修改操作都會去建立新的物件,然後變數重新指向新的物件,假設新增的元素足夠多,其效率可想而知。這裡的新增是指如下的操作( tupple 本身沒有新增的方法)
a = ()
for i in range(num):
a = a + (i,)
- debugger 難度
在之前的 [直接賦值,深拷貝和淺拷貝] 中提到可變物件,修改賦值後的變數,會對原有的變數造成影響,會導致其 value
值的改變,在實際開發過程中很容易被忽略
>>> a = [1, 3, 5, 7]
>>> b = a
>>> b[0] = -10
>>> a
[-10, 3, 5, 7]
什麼時候去使用 tupple 和 list
總結一下,list 和 tupple 的使用場景
- tupple 不存在新增和刪除的操作,更不存在修改的操作,如果有這些需求,不用使用 tupple,去用 list
- 如果只是遍歷的話, tupple 的速度是比 list 要快的
- 如果你有些資料是需要防寫,不希望在執行過程中被修改的話,用 tupple
- 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/