文章目錄
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字節。這是爲什麼呢?
- 由於列表是動態的,所以它需要存儲指針,來指向對應的元素(上述例子中,對於int型,8字節)。
- 由於列表可變,所以需要額外存儲已經分配的長度大小(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核心技術與實戰