列表(List)是Python中最基礎且強大的數據結構之一,但它的底層實現和特性遠比表面看起來復雜。本文將深入探討列表的各個方面。
1. 列表基礎特性
1.1 可變序列類型
lst = [1, 2, 3]
lst[1] = 20 # 可變性
1.2 異構容器
mixed = [1, "hello", 3.14, [1, 2]] # 可以包含不同類型
2. 底層實現原理
Python列表實際上是動態數組的實現,其關鍵特性:
- 動態擴容:當空間不足時,會按照約1.125倍(具體實現可能不同)進行擴容
- 連續內存:元素在內存中是連續存儲的(存儲的是對象引用而非對象本身)
- 預留空間:分配的空間通常比實際使用的多,以減少頻繁擴容
import sys
lst = []
for i in range(10):print(f"長度: {len(lst):2d}, 實際分配大小: {sys.getsizeof(lst)}字節")lst.append(i)
3. 時間復雜度分析
操作 | 時間復雜度 | 說明 |
---|---|---|
索引/取值 | O(1) | 直接計算內存偏移 |
追加(append) | 平均O(1) | 可能觸發擴容 |
插入(insert) | O(n) | 需要移動元素 |
刪除(del/pop) | O(n) | 需要移動元素 |
包含判斷(in) | O(n) | 需要遍歷 |
切片 | O(k) | k是切片大小 |
4. 列表推導式 vs 循環創建
# 列表推導式(更快,更Pythonic)
squares = [x**2 for x in range(10)]# 等效循環
squares = []
for x in range(10):squares.append(x**2)
列表推導式:
- 在字節碼層面更高效
- 有專門的優化處理
- 可讀性更強(對于簡單轉換)
5. 淺拷貝與深拷貝
import copyoriginal = [[1, 2], [3, 4]]
shallow = original.copy() # 淺拷貝
deep = copy.deepcopy(original) # 深拷貝original[0][0] = 99
print(shallow) # [[99, 2], [3, 4]] - 內部列表被共享
print(deep) # [[1, 2], [3, 4]] - 完全獨立
6. 列表常用模式
6.1 過濾
numbers = [1, 2, 3, 4, 5]
evens = [x for x in numbers if x % 2 == 0]
6.2 展平
nested = [[1, 2], [3, 4], [5]]
flat = [item for sublist in nested for item in sublist]
6.3 分組
data = [1, 2, 3, 4, 5, 6]
grouped = [data[i:i+2] for i in range(0, len(data), 2)]
7. 性能優化技巧
- 預分配空間:當知道大小時
lst = [None] * 1000 # 預分配
- 使用生成器表達式處理大數據
sum(x**2 for x in range(1000000)) # 不創建中間列表
- 避免頻繁中間插入:考慮使用collections.deque
8. 與其他序列類型比較
特性 | list | tuple | array.array | numpy.ndarray |
---|---|---|---|---|
可變性 | ? | ? | ? | ? |
異構元素 | ? | ? | ? | ? |
內存效率 | 低 | 低 | 高 | 高 |
數值計算 | 慢 | 慢 | 中等 | 快 |
9. 高級用法
9.1 自定義排序
users = [{'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}]
users.sort(key=lambda x: x['age'], reverse=True)
9.2 列表作為棧和隊列
# 棧
stack = []
stack.append(1) # push
stack.pop() # pop# 隊列(效率不高)
queue = []
queue.append(1) # enqueue
queue.pop(0) # dequeue (O(n)操作)
10. 常見陷阱
- 可變默認參數
def bad_func(value, lst=[]): # 同一個列表會被重復使用lst.append(value)return lst
- 循環中修改列表
# 危險!
lst = [1, 2, 3, 4]
for i, x in enumerate(lst):if x % 2 == 0:del lst[i] # 會跳過元素或越界
- 淺拷貝問題
a = [[]] * 3
a[0].append(1) # 所有子列表都會被修改
列表是Python的核心數據結構,理解其底層實現和特性對于編寫高效Python代碼至關重要。