迭代清單
避免在迴圈中取值
為了方便說明,我們從下面的例子開始:
lst = [1, 2, 3, 4 ,5]
要迭代這個清單並不難,但是不熟悉 Python 語言的朋友可能會想要這樣來迭代他:
for i in range(5):
print(lst[i])
或是:
for i in range(len(lst)):
print(lst[i])
這個兩個做法在大部分的程式語言裡面 (當要迭代 "類 array" 的資料結構時) 幾乎是標準的做法,前者是在已知序列長度的情況下,迭代個元素的 索引值 並在迴圈中利用索引值將對應的元素取出;而後者是在序列存在 詢問長度的方法 時的靈活作法。但不管是哪一種方法,他們迭代的策略都是繞行索引值並在迴圈中取出元素。
但這樣的手段不但不 pythonic 且大大複雜化了迭代,在 Python 中要迭代清單應該簡單地這樣做:
for e in lst:
print(e)
這樣就可以順利迭代清單中的每個元素了!
這邊引出了一個關於迭代好壞的基本概念,我們的迭代之旅也從這裡開始:
- 我們應當在迴圈中 專心處理邏輯 而 非取值,取值盡量在
for
述句中完成
同時迭代索引及元素
但有的時候我們的確需要元素的索引值,通常在我們需要知道該元素的序號時。
比如說有一個學生姓名的清單,依照本次考試成績來排序:
students = ['Bill', 'Cynthia', 'dokelung'] # 我們在此就簡單假設班上只有三個人
如果我們想要依序印出學生的名次及其姓名,我們就必須得想辦法也取得索引值,這個時候本節一開始的範例就顯得合理多了:
for i in range(len(students)):
print(i+1, students[i])
這段代碼會輸出:
1 Bill
2 Cynthia
3 dokelung
但是我們應該設法滿足我們剛剛的結論,盡量不要在迴圈中取值,比較 pythonic 的作法應該是:
for i, name in enumerate(students):
print(i+1, name)
enumerate
是 Python 中的內建函式,他接受一個可迭代物,並且會依次產生索引值和對應元素組成的 tuple:
>>> list(enumerate(students))
[(0, 'Bill'), (1, 'Cynthia'), (2, 'dokelung')]
在這裡我們同時利用了 拆解 的手法,讓我們在 for
述句中就完成了取索引值和元素的動作,於是在迴圈中就能專心地處理程式邏輯而避免干擾的取值動作。
不熟悉
enumerate
的朋友可以參見 Python Doc - enumerate。而關於拆解的詳細介紹請看後面章節的介紹。