1. 程式人生 > >[Python] list vs tupple

[Python] list vs tupple

# 前言 列表(list)和 元組(tupple) 是 Python 中常見的兩種資料結構.這兩者使用方法有一定的相似,倆者都是 Python 內建型別,都可以儲存資料集合,都可以儲存複合資料,我們同樣可以通過索引去訪問它們. 那麼問題來了,倆者究竟有區別嗎??? # list 和 tupple 的區別 首先回答問題.list 和 tupple 有區別嗎?答案是肯定的,兩者有區別. list 和 tupple 的本質區別在於,前者是一個可變物件而後者是一個不可變物件。 什麼是可變物件和不可變物件呢?**簡單地來說,可變物件就是建立之後可以修改,而不可變物件則是建立之後不允許在修改。** ![](https://img2020.cnblogs.com/blog/627405/202007/627405-20200704080357206-1128037820.png) 沒關係,讓我們看一下例子 首先建立一個 `list` ```python >>> a = ["a","b","c","d"] ``` 接著我們試著修改一下上面的 `list` , 將 `b` 改成 `e`,看看會發生什麼 ```python >>> a[1] = "e" >>> a ['a', 'e', 'c', 'd'] ``` 好像什麼都沒有發生~~ 沒關係,我們再來建立一個 `tupple` ```python >>> b=("a","b","c","d") ``` 同樣地,讓我們將 `tupple` 中的 `b` 改成 `e` ```python >>> b[1]="2" Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment ``` 為什麼同樣的賦值操作,在 `tupple` 中會出現錯誤呢?原因就是我們上面說到的 **`tupple` 是不可變物件,建立之後不能修改**。 有個小夥伴看見了 ![](https://img2020.cnblogs.com/blog/627405/202007/627405-20200704080423251-768050157.png) 然後給我寫了一段下面的程式碼 ```python >>> b=("a","b","c","d") >>> b=("a","e","c","d") >>>b >>>("a","e","c","d") ``` 這樣子是不是做到了修改 `tupple` 中的第2個元素呢?答案是否定的,為什麼呢?彆著急往下看 # 可變物件和不可變物件 在開始下面的內容之前,需要牢記一句話,**Python 中的變數是對在記憶體中 Python 物件的引用** 以我們上面的列表 `a` 為例 ```python >>> a = ["a","b","c","d"] ``` 它在記憶體中實際表現如下圖 ![](https://img2020.cnblogs.com/blog/627405/202007/627405-20200704080431674-316985774.png) 如果需要獲取列表 `list` 在記憶體的實際位置,我們可以借用內建函式 `id()` ```python >>> a=["a","b","c","d"] >>> id(a) 4557552456 ``` 現在我們去修改一下 a[1] 的值,然後再用 `id()` 這個函式去獲取 a 在記憶體的地址,你會發現它的值沒有改變,仍然指向相同位置 ```python >>> a[1] = "e" >>> id(a) 4557552456 ``` 整個過程如下圖 ![](https://img2020.cnblogs.com/blog/627405/202007/627405-20200704080459712-2033887495.png) 接下來我們看一下對 `tupple` 進行同樣的操作會有什麼變化 ```python >>> a=("a","b","c","d") >>> id(a) 4557412296 >>> a=("a","e","c","d") >>> id(a) 4557586504 ``` 不難發現,再修改之後指向記憶體中的地址發生了改變,這意味著這個時候變數 `a` 指向了一個全新的物件。 如果覺得難以理解,沒有關係,看下面的圖 ![](https://img2020.cnblogs.com/blog/627405/202007/627405-20200704080506179-9711428.png) 這個時候如果沒有其它變數指向之前的 `tupple`,Python 的 GC 將會把舊的 `tupple` 從記憶體中完全刪除. # 為什麼需要 list 和 tupple ? 其實更貼切的應該問,為什麼需要可變物件和不可變物件呢? 1. 新增元素效率 從上面的內容,我們知道一旦建立了 tupple,這個時候任何修改操作都會去建立新的物件,然後變數重新指向新的物件,假設新增的元素足夠多,其效率可想而知。這裡的新增是指如下的操作( tupple 本身沒有新增的方法) ```python a = () for i in range(num): a = a + (i,) ``` 2. debugger 難度 在之前的 [直接賦值,深拷貝和淺拷貝] 中提到可變物件,修改賦值後的變數,會對原有的變數造成影響,會導致其 `value` 值的改變,在實際開發過程中很容易被忽略 ```python >>> 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