enumerate
第一個是枚舉函數。
在我們的日常編程過程中,我們經常遇到一個問題。
在C語言和一些古老的語言中沒有迭代器的概念,所以當我們想要遍歷數組或容器時,我們只能使用下標。使用迭代器,我們的遍歷過程更加方便。我們可以直接使用變量來迭代容器中的值。最簡單的例子是數組遍歷。例如,我們需要遍歷items數組。我們可以直接:
for item in items:
通過迭代器的方法,可以方便地遍歷數組而不需要下標和計算數組的長度。但是如果我們需要知道循環體中元素的下標呢?
我們真的需要在下標和迭代器之間進行選擇嗎,比如在循環體之外添加一個變量來記錄下標?
idx = 0 for item in items: operation() idx += 1
這可以解決問題,但很麻煩,一點也不簡潔,專業術語也不是pythonic(Python標准代碼)。為了追求pythonic,我們使用了枚舉函數來解決直接迭代需要知道元素下標的情況。
它的用法也很簡單。我們將需要迭代的對象或迭代器傳遞到枚舉函數中。它將為我們創建一個新的迭代器,並返回下標和迭代的內容。舉個例子:
for i, item in enumerate(items):
此外,枚舉還支持傳入參數。例如,在某些情況下,我們希望下標從1開始,而不是從0開始。我們可以傳遞一個附加參數來實現這一點:
for i, item in enumerate(items, 1):
循環是我們編程中的一個基本操作。因此,枚舉函數得到了廣泛的應用。但是,應該注意的是,如果我們在一個多組數組上迭代,我們需要區分索引和值。例如:
data = [(1, 3), (2, 1), (3, 3)]
在不用enumerate的時候,我們有兩種迭代方式,這兩種都可以運行。
for x, y in data: for (x, y) in data:
但是,如果我們使用枚舉,因為引入了索引,我們必須進行區分,否則會報告錯誤,因此我們只有一種迭代方法:
for i, (x, y) in enumerate(data):
zip
接下來要介紹的另一個函數同樣是方便我們迭代的,不過它針對的是另一個場景——多對象迭代。
它的應用場景非常簡單,就是我們想要同時迭代多份數據,比如用戶的名字和用戶的職業數據是分開的,我們希望同時遍歷一個用戶的職業和名字。如果不使用zip,我們可能只能放棄迭代器回到傳統的下標遍歷的模式了。這樣當然是可以的,不過有兩個小問題,第一個小問題當然是代碼的可讀性變差了,不夠pythonic,第二個問題是我們需要維護兩個容器長度不一樣的情況,會增加額外的代碼。而使用zip,可以同時解決以上兩個問題。
我們來看一個例子:
最后輸出的結果是人名和職業的tuple:
xiaoming coach xiaohua student xiaohei student xiaoli student
在上面的示例中,名稱和作業的長度實際上不一致。使用zip時,它會根據較短的zip自動為我們截斷。如果我們不想截斷它,也可以在itertools下使用zip[最長]而不是zip:
from itertools import zip_longest for name, job in zip_longest(names, jobs):
這樣,長度不足的元素將填充為“無”。Zip﹣length提供了一個參數fillvalue,可以用我們指定的值填充它。
無論是Zip還是Zip﹣long EST,它都可以支持多個迭代器的遍歷。例如:
Zip不僅便於我們迭代,而且便於我們生成dict。例如,在剛才的例子中,如果我們想生成一個名稱和職業的dict,一般的方法是先定義一個dict,然后遍歷所有鍵和值來生成一個dict。但是,使用Zip,我們可以將這個操作簡化為一行代碼:
jobDict = dict(zip(names, jobs))
需要注意的是,我們調用zip的結果實際上是一個迭代器。當我們將其轉換為dict時,我們會自動遍歷迭代器的內容。例如,如果直接打印zip調用的結果,我們會發現屏幕上的輸出是迭代器的地址:
print(zip(names, jobs)) >>> <zip object at 0x10ec93b40>
我們想要獲得它的內容,需要將它手動轉成list:
print(list(zip(names, jobs))) >>> [('xiaoming', 'coach'), ('xiaohua', 'student'), ('xiaohei', 'student'), ('xiaoli', 'student')]
實際上,枚舉和zip的底層都是基於迭代器實現的。原則上,沒有深刻的內容,我們也不使用它們來編寫代碼。但Python之所以是Python,以及為什么許多人稱之為簡明語言和邏輯,是因為我們廣泛使用這些工具和方法來簡化代碼邏輯。所以我們很有必要去理解它。我希望每個人都能寫出Python IC的代碼,Python IC不僅在編寫代碼方面很強大,而且本身也很漂亮。