今天的原文的作者是來自國外的以為Python“佈道師”Dan Bader,他的部落格完全就是一個個人品牌的學校。有跟多Python技巧,有很多他錄製的Youtube視訊,國內的Pythonista們,不妨訂閱一下他的每週郵件推送。訂閱連結
今天的譯文是他部落格中的一篇,點選檢視原文
如何以去寫以及為什麼你應該使用Python中的內建列舉函式來編寫更乾淨更加Pythonic的迴圈語句?
Python的enumerate
函式是一個神話般的存在,以至於它很難用一句話去總結它的目的和用處。
但是,它是一個非常有用的函式,許多初學者,甚至中級Pythonistas是並沒有真正意識到。簡單來說,enumerate()
是用來遍歷一個可迭代容器中的元素,同時通過一個計數器變數記錄當前元素所對應的索引值。
讓我們來看一個示例:
names = [`Bob`, `Alice`, `Guido`]
for index, value in enumerate(names):
print(f`{index}: {value}`)
複製程式碼
這段程式碼會輸入如下內容:
0: Bob
1: Alice
2: Guido
複製程式碼
正如你所看到的,這個迴圈遍歷了names
列表的所有元素,並通過增加從零開始的計數器變數來為每個元素生成索引。
[如果您想知道上面例子中使用的f`…`字串語法,這是Python 3.6及更高版本中提供的一種新的字串格式化技巧。]
用enumerate()
讓你的迴圈更加Pythonic
那麼為什麼用enumerate()
函式去儲存執行中的索引很有用呢?
我發現,有很多從C或Java背景轉過來的新的Python開發人員有時使用下面這種range(len(...))
方法來儲存執行中每個元素的索引,同時再用for
迴圈遍歷列表:
# 警告: 不建議這麼寫
for i in range(len(my_items)):
print(i, my_items[i])
複製程式碼
通過巧妙地使用enumerate()
函式,就像我在上面的“names”例子中寫的那樣,你可以使你的迴圈結構看起來更Pythonic和地道。
你不再需要在Python程式碼中專門去生成元素索引,而是將所有這些工作都交給enumerate()
函式處理即可。這樣,你的程式碼將更容易被閱讀,而且減少寫錯程式碼的影響。(譯者注:寫的程式碼越多,出錯機率越高,儘量將自己的程式碼看起來簡潔,易讀,Pythonic,才是我們的追求)
修改起始索引
另一個有用的特性是,enumerate()
函式允許我們為迴圈自定義起始索引值。enumerate()
函式中接受一個可選引數,該引數允許你為本次迴圈中的計數器變數設定初始值:
names = [`Bob`, `Alice`, `Guido`]
for index, value in enumerate(names, 1):
print(f`{index}: {value}`)
複製程式碼
在上面的例子中,我將函式呼叫改為enumerate(names, 1)
,後面的引數1就是本次迴圈的起始索引,替換預設的0:
1: Bob
2: Alice
3: Guido
複製程式碼
OK,這段程式碼演示的就是如何將Python的enumerate()
函式預設0起始索引值修改為1(或者其他任何整形值,根據需求去設定不同值)
enumerate()
背後是如何工作的
你可能想知道enumerate()
函式背後是如何工作的。事實上他的部分魔法是通過Python迭代器來實現的。意思就是每個元素的索引是懶載入的(一個接一個,用的時候生成),這使得記憶體使用量很低並且保持這個結構執行很快。
讓我們演示一些更多的程式碼來表達我的意思:
>>> names = [`Bob`, `Alice`, `Guido`]
>>> enumerate(names)
<enumerate object at 0x1057f4120>
複製程式碼
在上面這個程式碼片段中,正如你所見,我使用了和前面一樣的示例程式碼。但是,呼叫enumerate()
函式並不會立即返回迴圈的結果,而只是在控制檯中返回了一個enumerate
物件。
正如你所看到的,這是一個“列舉物件”。它的確是一個迭代器。就像我說的,它會在迴圈請求時懶載入地輸出每個元素。
為了驗證,我們可以取出那些“懶載入”的元素,我計劃在這個迭代器上呼叫Python的內建函式list()
>>> list(enumerate(names))
[(0, `Bob`), (1, `Alice`), (2, `Guido`)]
複製程式碼
對於輸入list()
中的每個enumerate()
迭代器元素,迭代器會返回一個形式為(index,element)
的元組作為list的元素。在典型的for-in迴圈中,你可以利用Python的資料結構解包功能來充分利用這一點特性:
for index, element in enumerate(iterable):
# ...
複製程式碼
總結:Python中的enumerate函式 – 關鍵點
enumerate
是Python的一個內建函式。你應該充分利用它通過迴圈迭代自動生成的索引變數。- 索引值預設從0開始,但也可以將其設定為任何整數。
enumerate
函式是從2.3版本開始被新增到Python中的,詳情見PEP279。- Python的
enumerate
函式可以幫助你編寫出更加Pythonic和地道的迴圈結構,避免使用笨重且容易出錯的手動生成索引。 - 為了充分利用
enumerate
的特性,一定要研究Python的迭代器和資料結構解包功能。
譯者部落格:vimiix.com