[譯]Python的enumerate()函數揭祕

今天的原文的做者是來自國外的覺得Python「佈道師」Dan Bader,他的博客徹底就是一個我的品牌的學校。有跟多Python技巧,有不少他錄製的Youtube視頻,國內的Pythonista們,不妨訂閱一下他的每週郵件推送。訂閱連接python

今天的譯文是他博客中的一篇,點擊查看原文vim

如何以去寫以及爲何你應該使用Python中的內置枚舉函數來編寫更乾淨更加Pythonic的循環語句?數據結構

python-enumerate.jpg

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):
    # ...
複製代碼

總結:Python中的enumerate函數 - 關鍵點

  • enumerate是Python的一個內置函數。你應該充分利用它經過循環迭代自動生成的索引變量。
  • 索引值默認從0開始,但也能夠將其設置爲任何整數。
  • enumerate函數是從2.3版本開始被添加到Python中的,詳情見PEP279
  • Python的enumerate函數能夠幫助你編寫出更加Pythonic和地道的循環結構,避免使用笨重且容易出錯的手動生成索引。
  • 爲了充分利用enumerate的特性,必定要研究Python的迭代器和數據結構解包功能。

譯者博客:vimiix.com

相關文章
相關標籤/搜索