專項練習 · 8 分鐘閱讀

Python enumerate 與 zip 練習:更乾淨的迴圈

迴圈裡的大多數錯誤都來自記帳:索引悄悄偏移、計數器從錯誤的位置開始,或者兩個列表已經對不上卻沒人發現。enumerate 和 zip 把這些關係寫進迴圈頭部,讓問題更容易看見。

讓 enumerate 負責索引

迴圈變數會收到一對值,直接解包成索引和元素即可。不需要初始化計數器,也不會忘記加一。原列表保持不變。

colors = ["red", "green", "blue"]
for index, color in enumerate(colors):
    print(index, color)

一次拿到索引和值

選擇適合人的起始編號

計算機通常從零開始數,但人往往期待從一開始。start 參數只改變編號,不會切片,也不會跳過第一個元素。

for number, color in enumerate(["red", "green"], start=1):
    print(f"{number}: {color}")

從一編號

用 zip 並行走訪列表

zip 先配第一項,再配第二項,依此類推,並在最短的輸入處停止。偵錯時可以列印 list(zip(...)),直接看到配對,而不是一個迭代器物件。

names = ["Ada", "Grace"]
scores = [92, 88]
for name, score in zip(names, scores):
    print(f"{name}: {score}")

兩個列表,一個迴圈

長度必須一致時使用嚴格 zip

悄悄截斷對某些資料很方便,對另一些資料卻很危險。Python 3.10 增加了 strict=True,輸入長度不同時會拋出 ValueError。缺失一行應該被看見時,就用它。

pairs = list(zip([1, 2], ["a", "b"], strict=True))
print(pairs)

資料不比對時明確失敗

用兩個列表建構字典

dict 接收由鍵值對組成的可迭代物件,而 zip 產生的正是這種形狀。如果源資料可能重複,先檢查重複鍵;同一個鍵出現兩次時,dict 會保留後面的值。

names = ["Ada", "Grace"]
scores = [92, 88]
print(dict(zip(names, scores)))

配對變成映射

你的練習清單

常見問題

enumerate 會複製列表嗎?

不會。它回傳一個迭代器,讀取已有的可迭代物件並產生索引-元素對。

zip 為什麼會提前停止?

只要有任意一個輸入用完,zip 就結束。這讓它可以配合無限迭代器,但也可能掩蓋缺失資料。

可以同時 zip 三個列表嗎?

可以。zip 接受任意數量的可迭代物件,並產生包含每個輸入一個值的元組。

練習 enumerate 與 zip

12 道題,覆蓋索引、並行列表、嚴格 zip 和字典建構。

打開練習

繼續閱讀: