for循環是每個編程語言中必不可少的流程控制語句。在Python中,for用於遍歷一個迭代對象的所有元素。循環內的語句會對每個元素都執行一次,類似遍歷一個集合。
簡單的遍歷,如下,該for循環將list中的每個數字打印了一遍:
語法:
for element in iterable: statements(s)
iterable即迭代對象,當一個迭代對象作為參數傳給iter()方法時,會返回一個迭代器對象:
迭代器
迭代器在Python中被定義為一個表現為流式數據的對象。
將對象傳遞給內置的next()方法時,它會從與之關聯的流式數據中返回下一個值,一旦所有數據都遍歷結束,就會拋出一個”StopIteration“異常
迭代器遍歷元素的過程
當一個循環開始時,首先會獲取它的迭代器。for循環會調用該迭代器的__next__()方法,獲取迭代器的下一個元素,並執行代碼塊中的語句。當next到最后發現Stopiteration異常時,循環結束
iter()方法要求傳入的是可迭代對象,才會返回一個迭代器。而產生的迭代器也同樣是一個迭代對象(因為迭代器本身支持迭代器協議),它同樣可以被iter(0方法所迭代,得到另一個迭代器。
它和普通迭代對象(如list列表)不同的是,普通迭代對象傳入iter(),每次都返回不同的迭代器,而在迭代器上調用iter(),都是返回同一個迭代器(地址是同一個)
這里有幾個簡單的概念需要了解一下:
迭代:即逐個獲取元素的過程,也可以叫遍歷
可迭代:即實現了__iter__方法的對象。基本上Python中的有序列表都是可迭代的。
迭代器:即實現了__next__方法的對象。使用next(),迭代器會返回下一個值,若沒有返回的值了,則返回Stopiteration異常。
迭代器與普通列表的區別在於,列表會將所有元素一次性加載到內存,而迭代器以延遲計算的方式返回元素,即按需調用。在for循環中,通過不斷調用迭代器的next方法,實現遍歷
生成器
當對有規律的列表進行操作,那么我們可以無需一次性生成所有元素,而是元素邊用邊生成的方式來處理,減小了資源的占用,也feel更upper一些。
這個定義聽起來和迭代器沒有什么差異,先來看一下如何得到一個生成器吧:
1.使用生成器函數
普通函數使用return返回值,而生成器函數使用yield來返回值,返回的對象就是一個生成器對象,生成器本質上就是一個迭代器,因此與迭代器有相同的特性
調用生成器函數時並執行時,此處的yiels會掛起該函數,並向調用者返回一個值,但保留足夠的狀態使得函數能從它離開的地方繼續。
當繼續時,函數在上一個yield返回后立即繼續執行。從函數的角度看,yield允許了代碼按時間產生一系列值,而不是一次性計算並返回給調用者。
2.生成器表達式
與列表生成式非常相似,僅僅把 [ ] 改成了 ( ) ,二者返回的對象不同。(圖中錯誤請忽略)
至於迭代器與生成器的不同之處,網上的文章並沒有什么多余的解釋。
在《Python學習手冊 第四版》中,同樣說到這個話題,但從字里行間可以看得出來,這兩個概念沒有嚴格的區分,迭代器偏向描述一個對象的可迭代性;而生成器則添加了一個掛起的功能