pyhton的內置類型(2)----列表和元組

1. 列表和元組的區別

1. 相同點
  • 列表和元組,都是一個可以放置任意數據類型的有序集合
    在絕大多數編程語言中,集合的數據類型必須一致。不過,對於Python的列表和元組來說,並無此要求.

    list_test = [6, 2, 'hello', 'world']  # 列表中同時含有int和string類型的元素
    [6, 2, 'hello', 'world']
    tuple_test = ('jason', 22) # 元組中同時含有int和string類型的元素
    tup('jason', 22)
    
  • Python中的列表和元組都支持負數索引 -1表示最後一個元素,-2表示倒數第二個元素,以此類推。

  • 列表和元組都支持切片操作

  • 列表和元組都可以隨意嵌套

  • 兩者也可以通過list()和tuple()函數相互轉換

2. 不同點
  • 列表是動態的,長度大小不固定,可以隨意地增加、刪減或者改變元素(mutable)。列表的存儲空間略大於元組,性能略遜於元組
  • 而元組是靜態的,長度大小固定,無法增加刪減或者改變(immutable)。元組相對於列表更加輕量級,性能稍優.

2.列表常用的內置函數

方法 意義
L.index(v [, begin[, end]]) 返回對應元素的索引下標, begin爲開始索引,end爲結束索引,當 value 不存在時觸發ValueError錯誤
L.insert(index, obj) 將某個元素插放到列表中指定的位置
L.count(x) 返回列表中元素的個數
L.remove(x) 從列表中刪除第一次出現在列表中的值
L.copy() 複製此列表(只複製一層,不會複製深層對象)
L.append(x) 向列表中追加單個元素
L.extend(lst) 向列表追加另一個列表
L.clear() 清空列表,等同於 L[:] = []
L.sort(reverse=False) 將列表中的元素進行排序,默認順序按值的小到大的順序排列
L.reverse() 列表的反轉,用來改變原列表的先後順序
L.pop([index]) 刪除索引對應的元素,如果不加索引,默認刪除最後元素,同時返回刪除元素的引用關係

3.元組常用的內置函數

方法 說明
T.index(v [, begin[, end]]) 返回對應元素的索引下標, begin爲開始索引,end爲結束索引,當 value 不存在時觸發ValueError錯誤
T.count(x) 返回元組中對應元素的個數

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

4. 列表和元組的不同的存儲方式

l = [1, 2, 3]
l.__sizeof__() # 64
tup = (1, 2, 3)
tup.__sizeof__()  # 48
1. 對列表和元組,我們放置了相同的元素,但是元組的存儲空間,卻比列表要少16字節。這是爲什麼呢?
  1. 由於列表是動態的,所以它需要存儲指針,來指向對應的元素(上述例子中,對於int型,8字節)。
  2. 由於列表可變,所以需要額外存儲已經分配的長度大小(8字節),這樣纔可以實時追蹤列表空間的使用情況,當空間不足時,及時分配額外空間。
2. 列表空間分配的過程
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)

  • 對於元組,情況就不同了。元組長度大小固定,元素不可變,所以存儲空間固定

5. 列表和元組的性能

  • 初始化一個相同元素的列表和元組分別所需的時間。元組的初始化速度,要比列表快5倍左右。
  • 索引操作,兩者的速度差別非常小,幾乎可以忽略不計
  • 增加、刪減或者改變元素,那麼列表顯然更優

6. 列表和元組的初始化方式

python3 -m timeit 'empty_list = list()'
10000000 loops, best of 3: 0.094 usec per loop
python3 -m timeit 'empty_list = []'
10000000 loops, best of 3: 0.0246 usec per loop
python3 -m timeit 'empty_list = ()'
100000000 loops, best of 3: 0.0152 usec per loop
python3 -m timeit 'empty_list = tuple()'
10000000 loops, best of 3: 0.0798 usec per loop

由此可見,初始化列表和元組的時候,我們應儘量使用[]和()
原因:
list()是一個function call,Python的function call會創建stack,並且進行一系列參數檢查的操作,比較expensive,反觀[]是一個內置的C函數,可以直接被調用,因此效率高

  • 性能和存儲方式參考自極客時間景霄老師的python核心技術與實戰
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章