for循環工作機制
字符串、列表、元組、詞典、set等數據類型都可以用for循環遍歷。
字符串、列表、元組這些有序數據也可以用索引while循環,像字典、set等數據類型沒有索引,所以就有for循環
可以直接作用for循環的對象統稱爲 可迭代對象: Iterable。
for循環遍歷數據本質做了兩件事:
1:調用數據類型的內置方法 iter(),,使之變成一個迭代器對象:
2:變成迭代器之後,循環調用next()方法讀取數據:
迭代器
對於序列類型:字符串、列表、元組,我們可以使用索引的方式迭代取出其包含的元素。但對於字典、集合、文件等類型是沒有索引的,若還想取出其內部包含的元素,則必須找出一種不依賴於索引的迭代方式,這就是迭代器
迭代器對象表示的是一個數據流,Iterator對象可以被next()函數調用並不斷返回下一個數據,直到沒有數據時拋出StopIteration錯誤。可以把這個數據流看做是一個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()函數實現按需計算下一個數據,所以Iterator的計算是惰性的,只有在需要返回下一個數據時它纔會計算。
Iterator甚至可以表示一個無限大的數據流,例如全體自然數。而使用list是永遠不可能存儲全體自然數的。
**凡是可作用於for循環的對象都是Iterable類型;
凡是可作用於next()函數的對象都是Iterator類型,它們表示一個惰性計算的序列;
集合數據類型如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函數獲得一個Iterator對象。
Python的for循環本質上就是通過不斷調用next()函數實現的
生成器
生成器也是迭代器,區別就是迭代器需要使用iter() 方法才能生成一個迭代器對象,生成器不需要使用 iter方法
生成器創建方式:
list可以直接打印出每個元素,generator不行。可以通過next()函數獲得下一個返回值。
generator保存的是算法,每次調用next(g),就計算出g的下一個元素的值,直到計算到最後一個元素,沒有更多的元素時,拋出StopIteration的錯誤。
generator也是一個可迭代對象,可以用for循環
定義generator的另一種方法。如果一個函數定義中包含yield關鍵字,那麼這個函數就不再是一個普通函數,而是一個generator。
generator和函數的執行流程不一樣。函數是順序執行,遇到return語句或者最後一行函數語句就返回。而變成generator的函數,在每次調用next()的時候執行,遇到yield語句返回,再次執行時從上次返回的yield語句處繼續執行。
調用該generator時,首先要生成一個generator對象,然後用next()函數不斷獲得下一個返回值
generator,在執行過程中,遇到yield就中斷,下次又繼續執行。執行3次yield後,已經沒有yield可以執行了,所以,第4次調用next(o)就報錯。
區分普通函數和generator函數,普通函數調用直接返回結果。generator函數的“調用”實際返回一個generator對象。