今天的原文的做者是來自國外的覺得Python「佈道師」Dan Bader,他的博客徹底就是一個我的品牌的學校。有跟多Python技巧,有不少他錄製的Youtube視頻,國內的Pythonista們,不妨訂閱一下他的每週郵件推送。訂閱連接python
今天的譯文是他博客中的一篇,點擊查看原文vim
如何以去寫以及爲何你應該使用Python中的內置枚舉函數來編寫更乾淨更加Pythonic的循環語句?數據結構
Python的enumerate
函數是一個神話般的存在,以致於它很難用一句話去總結它的目的和用處。函數
可是,它是一個很是有用的函數,許多初學者,甚至中級Pythonistas是並無真正意識到。簡單來講,enumerate()
是用來遍歷一個可迭代容器中的元素,同時經過一個計數器變量記錄當前元素所對應的索引值。oop
讓咱們來看一個示例:ui
names = ['Bob', 'Alice', 'Guido']
for index, value in enumerate(names):
print(f'{index}: {value}')
複製代碼
這段代碼會輸入以下內容:spa
0: Bob
1: Alice
2: Guido
複製代碼
正如你所看到的,這個循環遍歷了names
列表的全部元素,並經過增長從零開始的計數器變量來爲每一個元素生成索引。code
[若是您想知道上面例子中使用的f'...'字符串語法,這是Python 3.6及更高版本中提供的一種新的字符串格式化技巧。]orm
enumerate()
讓你的循環更加Pythonic那麼爲何用enumerate()
函數去保存運行中的索引頗有用呢?cdn
我發現,有不少從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):
# ...
複製代碼
enumerate
是Python的一個內置函數。你應該充分利用它經過循環迭代自動生成的索引變量。enumerate
函數是從2.3版本開始被添加到Python中的,詳情見PEP279。enumerate
函數能夠幫助你編寫出更加Pythonic和地道的循環結構,避免使用笨重且容易出錯的手動生成索引。enumerate
的特性,必定要研究Python的迭代器和數據結構解包功能。譯者博客:vimiix.com