What?(Python迭代器是什麼?)python
在使用Python進行編程時,常常會使用for語句對一個對象進行遍歷,獲取所需數據,如編程
li = [1, 2, 3, 4, 5] for i in li: print i
像list、dict、string這一類可使用for語句直接進行遍歷的對象,稱之爲可迭代對象(Iterable),所謂可迭代對象,即爲一類實現了__iter__()方法的對象,這類對象經過__iter__()方法返回一個迭代器,從而實現迭代操做;而所謂的迭代器對象(Iterator),即爲一類實現了next()方法的對象,這類對象經過next()方法在必定範圍內返回用戶所指望的數據,超出範圍則拋出StopIteration異常,並終止迭代函數
How?(如何建立並使用迭代器對象?)工具
下面這段代碼自定義了一個迭代器對象MyIter,經過遍歷該對象,能夠得到[0, n)範圍內的全部天然數spa
能夠看到,MyIter既實現了__iter__()方法,又實現了next()方法,因此MyIter對象既是可迭代對象,又是迭代器對象code
那麼這中兼具雙重身份的對象與單純的可迭代對象又有什麼區別呢?對象
下面先看以下這個例子,這個例子將MyIter對象與list對象進行了一次比較內存
上圖中,方框1&2和方框3&4分別爲對MyIter和list對象返回的迭代器進行兩次迭代操做的結果,由結果可知,MyIter的迭代器只能進行一次迭代操做,而list的迭代器能夠進行屢次迭代操做。string
緣由:這主要是由於兼具雙重身份的迭代器對象,每次經過iter()方法返回的都是該對象自身,而後經過該對象自身的next()方法實現遍歷操做,因此當執行完一次遍歷操做後,該對象的next()函數就到了越界的位置,下次再對該對象進行遍歷時,就已經處於越界位置,因此返回結果應該爲一個StopIteration異常。而單純的可迭代對象,每次調用iter()函數時都會返回一個指定的迭代器對象的新實例,因此執行幾回iter()方法就會產生幾個不一樣的迭代器實例,每次迭代時,都是調用不一樣的迭代器實例的next()方法返回相應的數據,因此該類可迭代對象就能實現屢次遍歷操做。it
驗證:本身實現一個單純的可迭代對象
能夠看到,在上面例子中,兩次對MyPureIter對象進行迭代,會獲得兩次迭代結果,這和上面的list的效果是相同的,從而驗證了咱們的說法。因此當咱們須要屢次對同一個可迭代對象進行迭代操做時,須要採用這種方式。
What?
Python生成器是一個能有快速建立迭代器的強有力的工具。生成器看上去和普通函數相似,可是當須要返回數據時,使用yield關鍵字進行聲明,而非return關鍵字。每次調用生成器的next()函數時,生成器會返回yield關鍵字後面的內容,並記住此次的返回位置和函數內部變量狀態,用於下一次調用時進行恢復。
How?
建立生成器
下面的示例演示了經過yield關鍵字生成一個迭代器的過程
生成器的特色
生成器會自動生成迭代器的__iter__()方法和next()方法
在兩次調用間函數的執行狀態和局部變量會自動保存
生成器的執行流程
第一次調用:i=0, yield i,返回0,保存變量i的值0及此次函數執行的位置
第二次調用:恢復函數狀態i=0,i += 1, 從而i=1,返回1,保存變量i的值1及此次函數執行的位置
。。。
第五次調用:恢復函數狀態i=3,i += 1, 從而i=4,返回1,保存變量i的值1及此次函數執行的位置
第六次調用:恢復函數狀態i=4,i += 1, 從而i=5,i>=n,函數結束
Why?
使用生成器可以比較方便快速地得到一個迭代器
使用生成器時採用的是惰性生成法則,只有須要時才生成相應的值,這樣是內存友好的
生成器表達式有點相似於列表表達式
列表表達式:[expr for i in iterable if cond_expr](下面左圖)
生成器表達式:(expr for i in iterable if cond_expr)(下面右圖)
列表表達式與生成器表達式:
二者的寫法不一樣,前者是中括號,後者是小括號
二者返回的值不一樣,前者返回一個列表,後者返回一個生成器
二者的做用不一樣,前者能夠進行重複操做,屢次迭代;後者只能進行一次迭代
後者比前者更加內存友好,因此當每次只須要返回一個值,而且不須要進行重複操做時,應該使用生成器表達式;而當一次須要使用列表中多個值,或者須要對列表元素進行屢次操做時,則須要使用列表表達式
Python迭代器是一類實現了__iter__()方法和next()方法的對象
對於一個可迭代對象,for語句能夠經過iter()方法得到該對象的迭代器對象,而後經過迭代器對象的next(0方法依次得到想要的元素
當可迭代對象同時也是迭代器對象時,沒法進行獨立的迭代操做;而像list這類可迭代對象,其迭代器對象是獨立存在的,這時就能夠重複進行迭代操做
生成器是一類特殊的函數,這類函數不經過return語句返回值,而是經過yield關鍵字返回一次返回一個結果,經過使用生成器,能夠比較方便快捷地得到迭代器對象
生成器表達式與列表表達式很是類似,不過二者的具體使用場景和做用不一樣,須要根據具體使用場景選擇相信的表達式