迭代 通常意義上的迭代是指:重覆執行一系列運算,從前面的量依次推出後面的量的過程,每一次迭代的結果,會作為下一次迭代的初始值。 在c、c++、java等編程語言中的for迴圈語句,就是一個迭代過程,例如: 這種for迴圈語句比較符合迭代的含義,for語句中給定了一個初始輸入 i=0 ,然後開始執行一 ...
迭代
通常意義上的迭代是指:重覆執行一系列運算,從前面的量依次推出後面的量的過程,每一次迭代的結果,會作為下一次迭代的初始值。
在c、c++、java等編程語言中的for迴圈語句,就是一個迭代過程,例如:
for(int i=0;i<100;i++) { cout << i << endl; }
這種for迴圈語句比較符合迭代的含義,for語句中給定了一個初始輸入 i=0 ,然後開始執行一個重覆推導變數 i 是否小於 100 ,如果小於就對 i 加1並執行迴圈體中代碼的過程,且每次執行後的結果將作為下一次推導的輸入值,這個過程就是迭代。
python中,也使用了 for 關鍵字來實現類似過程,具體形式為 for ... in ... ,當然迭代過程也可以通過while迴圈語句等來實現,但不在本文討論範疇,這裡不做說明。在python中通常使用 for ... in ... 的形式來遍歷一個list或tuple等對象,這種遍歷過程,通常稱為迭代(Iteration)。例如:
上圖中,通過for語句來遍歷列表L,實現語句塊的重覆執行過程。這裡之所以每次迭代時都讓num的值加3,是為了說明語句塊中對num進行修改後的值並不會帶入到下一次迭代過程,這裡應註意與C、C++、java等語言的for迴圈語句的區別。至於為什麼是這樣,可以查閱python語法中for語句的執行原理,這裡不再詳述。
可迭代對象與迭代器
可迭代對象:使用內置iter函數可以獲取迭代器的對象,稱為可迭代對象。通常指實現了能返回迭代器的__iter__方法或實現了__getitem__方法且其參數從0開始索引的對象。
迭代器:指實現了無參數的__next__方法的對象。__next__方法返回序列中的下一個元素;如果沒有元素了,則拋出StopIteration異常。通常情況下,迭代器也應該實現__iter__方法,迭代器的__iter__方法應該返回其自身(self),因為實現了__iter__方法,所以迭代器可迭代。
區別與聯繫:迭代器可以迭代,但可迭代對象不是迭代器。可迭代對象一定不能是自身的迭代器,即可迭代對象一定不能實現__next__方法;迭代器應該一直可以迭代,其__iter__方法應該返回自身。示例:
class IteratorObj: def __init__(self, max): self.a = 0 self.b = 1 self.max = max def __iter__(self): return self def __next__(self): self.a, self.b = self.b, self.a + self.b if self.a > self.max: raise StopIteration() return self.a class IterableObj: def __init__(self, max): self.max = max def __iter__(self): return IteratorObj(self.max)
python中for迴圈遍歷的本質就是調用遍歷對象的__iter__方法,得到一個迭代器,再調用迭代器的__next__方法依次獲取對象的值並自動捕獲StopIteration異常。
生成器
生成器是一種特殊的迭代器,可通過使用迭代器的方法使用生成器。
python定義生成器的方法有兩種:
生成器函數:使用普通函數的定義語法定義,但函數體內必須包含yield關鍵字,即包含yield語句的函數都被稱為生成器。生成器函數雖然看上去像函數,但與函數的行為截然不同。區別在於生成器函數不是使用return語句返回一個值,而是可以生成多個值,每次生成一個。每次使用yield生成一個值後,函數被中斷,在此處停止執行,再次被調用時,函數將從上一次停止的地方開始繼續執行。例如:
註意:當生成器因沒有可生產的值退出時,同樣會拋出StopIteration異常。
生成器表達式:類似於列表推導,只不過要將列表推導中的[]換成()。例如:
上圖中,當第6次調用next(g)時,因沒有值可生產而拋出了StopIteration異常。
以上。