首先,明確可迭代對象、迭代器和生成器這三個概念。
可迭代對象(Iterable Object),簡單的來理解就是可使用 for 來循環遍歷的對象。好比常見的 list、set和dict。html
可迭代對象具備__iter__ 方法,用於返回一個迭代器,或者定義了 getitem 方法,能夠按 index 索引的對象(而且可以在沒有值時拋出一個 IndexError 異常),所以,可迭代對象就是可以經過它獲得一個迭代器的對象。因此,可迭代對象均可以經過調用內建的 iter() 方法返回一個迭代器。python
可迭代器對象具備以下的特性:express
能夠 for 循環: for i in iterable;socket
能夠按 index 索引的對象,也就是定義了 getitem 方法,好比 list,str;函數
定義了__iter__ 方法,能夠隨意返回;spa
能夠調用 iter(obj) 的對象,而且返回一個iterator。code
能夠經過isinstance(obj, collections.Iterable) 來判斷對象是否爲可迭代對象。協程
傳送門之迭代器實現原理htm
首先明確它是一個帶狀態的對象。對象
Python的for循環本質上就是經過不斷調用next()函數實現的,舉個栗子,下面的代碼
x = [1, 2, 3] for elem in x: ...
實際上執行時是
生成器實際上是一種特殊的迭代器,不過這種迭代器更加優雅。它不須要再像上面的類同樣寫__iter__()和__next__()方法了,只須要一個yiled關鍵字。
Python對協程的支持是經過generator實現的。
生成器表達式是列表推倒式的生成器版本,看起來像列表推導式,可是它返回的是一個生成器對象而不是列表對象。
>>> a = (x*x for x in range(10)) >>> a <generator object <genexpr> at 0x401f08> >>> sum(a) 285
容器是一系列元素的集合,str、list、set、dict、file、sockets對象均可以看做是容器,容器均可以被迭代(用在for,while等語句中),所以他們被稱爲可迭代對象。
可迭代對象實現了__iter__方法,該方法返回一個迭代器對象。
迭代器持有一個內部狀態的字段,用於記錄下次迭代返回值,它實現了__next__和__iter__方法,迭代器不會一次性把全部元素加載到內存,而是須要的時候才生成返回結果。
生成器是一種特殊的迭代器,它的返回值不是經過return而是用yield。