Python collections 練習:計數、分組與佇列
collections 模組提供一組減少樣板程式碼的小工具。你不需要手寫計數迴圈、缺失鍵判斷或佇列,而是直接選擇行為已經比對問題的容器。
先計數,再查詢
Counter 把可迭代物件轉換成計數。它是字典子類,所以缺失鍵讀取為零,同時仍可使用普通映射方法。most_common 適合快速排序,直接索引適合單次查詢。
from collections import Counter
votes = ["yes", "no", "yes", "yes"]
counts = Counter(votes)
print(counts["yes"])
print(counts.most_common(1))一次計數,多次查詢
給缺失鍵合理的預設值
defaultdict 在鍵不存在時呼叫工廠函式。使用 list 時可以直接 append,不必先判斷鍵是否存在。工廠必須可呼叫,預設值只在存取該鍵時建立。
from collections import defaultdict
groups = defaultdict(list)
for word in ["ant", "ape", "bee"]:
groups[word[0]].append(word)
print(dict(groups))分組時不再判斷鍵
兩端都重要時用 deque
列表在右端操作高效,在左端操作代價較高。deque 支援在兩端快速添加和彈出。佇列可以用 appendleft 和 popleft,需要迴圈移動元素時可以用 rotate。
from collections import deque
queue = deque(["a", "b"])
queue.append("c")
queue.popleft()
print(list(queue))兩端操作都很快
把計數當作可運算的值
Counter 支援計數相加和相減。比較兩組物品時很方便,但相減會丟棄非正數結果。update 可以從另一個可迭代物件或映射累加計數。
from collections import Counter
first = Counter("aab")
second = Counter("abb")
print(first + second)
print(first - second)計數也能組合
按需要的操作選擇容器
根據最常執行的操作選擇容器:計數、分組還是兩端存取。如果既不需要預設值也不需要計數,普通 dict 仍然最合適。可讀性來自工具與任務比對,而不是在一個檔案裡用遍所有容器。
from collections import Counter, deque
print(Counter("aba").most_common(1))
print(deque([1, 2, 3]).popleft())讓容器比對任務
你的練習清單
- 需要頻率而不只是成員判斷時使用 Counter。
- 用 defaultdict(list) 分組,避免預先建立列表。
- 佇列和左端高頻操作使用 deque。
- 記住 Counter 相減會丟棄非正計數。
- 根據最常重複的操作選擇容器。
常見問題
Counter 是字典嗎?
是。Counter 是 dict 的子類,查詢缺失鍵時按零處理。
什麼時候用 defaultdict 而不是 dict.get?
當同一個缺失鍵預設值在迴圈中反覆出現時用 defaultdict。只查一兩次時,dict.get 通常更清楚。
deque 可以索引嗎?
可以,但索引不是使用 deque 的主要理由。兩端頻繁增刪才是它最合適的場景。
練習 collections
12 道題,覆蓋 Counter、defaultdict、deque、分組和容器選擇。
繼續閱讀: