[Python進階] 1. 列表與元組

[Python進階] 1. 列表與元組

一、基礎知識

  1. 列表和元組,都是一個可以放置任意數據類型的有序集合,列表或元組中的元素數據類型不需要保持一致。
  2. 列表是mutable而元組是immutable
  3. Python中的列表和元組都支持負數索引,-1表示最後一個元素。
  4. 列表和元組都支持切片操作,且都可以隨意嵌套。
  5. 兩者可以通過 list()tuple() 函數相互轉換。
列表和元組常用的內置函數

count(item) 表示統計列表 / 元組中 item 出現的次數。
index(item) 表示返回列表 / 元組中 item 第一次出現的索引。
list.reverse()list.sort() 分別表示原地倒轉列表和排序(注意,元組沒有內置的這兩個函數)。
reversed()sorted() 同樣表示對列表 / 元組進行倒轉和排序,但是會返回一個倒轉後或者排好序的新的列表 / 元組。

二、列表和元組的存儲方式

>>> l = [1, 2, 3]
>>> l.__sizeof__()
64
>>> tup = (1, 2, 3)
>>> tup.__sizeof__()
48

上面結果表明對於相同元素的元組與列表,元組的存儲空間比列表要少 16 字節。

  • 由於列表是動態的,所以它需要存儲指針,來指向對應的元素,int型指針佔8個字節。
  • 由於列表可變,所以需要額外存儲已經分配的長度大小(8 字節),這樣纔可以實時追蹤列表空間的使用情況,當空間不足時,及時分配額外空間。
>>> l = []
>>> l.__sizeof__() #空列表的存儲空間爲 40 字節
40
>>> l.append(1)
>>> l.__sizeof__()
72 #加入了元素 1 之後,列表爲其分配了可以存儲 4 個元素的空間 (72 - 40)/8 = 4
>>> l.append(2)
>>> l.__sizeof__()
72 #由於之前分配了空間,所以加入元素 2,列表空間不變
>>> l.append(3)
>>> l.__sizeof__()
72
>>> l.append(4)
>>> l.__sizeof__()
72
>>> l.append(5)
>>> l.__sizeof__()
104 #加入元素5之後,列表的空間不足,所以又額外分配了可以存儲 4 個元素的空間

列表空間分配:爲了減小每次增加 / 刪減操作時空間分配的開銷,Python 每次分配空間時都會額外多分配一些,這樣的機制 (over-allocating)保證了其操作的高效性:增加 / 刪除的時間複雜度均爲 O(1)。

三、列表和元組的性能

由存儲方式的區別可以得出結論:元組要比列表更加輕量級一些,所以總體上來說,元組的性能速度要略優於列表。

Python 會在後臺,對靜態數據做一些資源緩存(resource caching)。通常來說, 因爲垃圾回收機制的存在,如果一些變量不被使用了,Python 就會回收它們所佔用的內存,返還給操作系統,以便其他變量或其他應用使用。
但是對於一些靜態變量,比如元組,如果它不被使用並且佔用空間不大時,Python 會暫時緩存這部分內存。這樣,下次我們再創建同樣大小的元組時,Python 就可以不用再向操作系統發出請求,去尋找內存,而是可以直接分配之前緩存的內存空間,這樣就能大大加快程序的運行速度。

  1. 計算初始化一個相同元素的列表和元組分別所需的時間。可以看到,元組的初始化速度,要比列表快 5 倍。

    python3 -m timeit 'x=(1,2,3,4,5,6)'
    20000000 loops, best of 5: 13.5 nsec per loop
    python3 -m timeit 'x=[1,2,3,4,5,6]'
    5000000 loops, best of 5: 67.7 nsec per loop
    
  2. 如果是索引操作的話,兩者的速度差別非常小,幾乎可以忽略不計。

    python3 -m timeit -s 'x=[1,2,3,4,5,6]' 'y=x[3]'
    10000000 loops, best of 5: 30.1 nsec per loop
    python3 -m timeit -s 'x=(1,2,3,4,5,6)' 'y=x[3]'
    10000000 loops, best of 5: 30.2 nsec per loop
    
  3. 如果增加、刪減或者改變元素,那麼顯然列表更優,因爲元組要重新開闢內存空間。

四、列表和元組的使用場景

  1. 元組適用於存儲的數據和數量不變。
  2. 列表適用於存儲的數據或數量是可變的。

五、總結

列表是動態的,長度可變,可以隨意的增加、刪減或改變元素。列表的存儲空間略大於元組,性能略遜於元組。
元組是靜態的,長度大小固定,不可以對元素進行增加、刪減或者改變操作。元組相對於列表更加輕量級,性能稍優。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章