如教程所說,迭代器和生成器算是 python 一大特色,其核心是基於迭代器協議來的。
而平時我們經常使用的 for in 迴圈體,本質就是迭代器協議的一大應用。
同時 python 內建的集合型別(字元、列表、元組、字典)都已經實現了迭代器協議,所以才能使用 for in 語句進行迭代遍歷。for in 迴圈體在遇到 stopiteration 異常時,便終止迭代和遍歷。
再說下可迭代、迭代器、生成器三個概念的聯絡和區別。
1、可迭代概念範圍最大,生成器和迭代器肯定都可迭代,但可迭代不一定都是迭代器和生成器,比如上面說到的內建集合類資料型別。可以認為,在 python 中,只要有集合特性的,都可迭代。
2、迭代器,迭代器特點是,均可以使用 for in 和 next 逐一遍歷。
3、生成器,生成器一定是迭代器,也一定可迭代。
至於 python 中為何要引入迭代器和生成器,除了節省記憶體空間外,也可以顯著提公升**執行速度。
自定義迭代器類示例和說明如下:
class myiter():
def __init__(self):
#為了示例,用乙個簡單的列表作為需迭代的資料集合,並且私有化可視情況變為其他型別集合
self.__list1=[1,2,3,4]
self.__index=0
def __iter__(self):
#該魔法方法,必須返回乙個迭代器物件,如果self已經定義了__next__()魔法方法,則只需要返回self即可
#因為如上面所述,生成器一定是迭代器
return iter(self.list1)
def __next__(self):
#此處的魔法函式,python會自動記憶每次迭代的位置,無需再使用yield來處理
#在使用next(obj)時,會自動呼叫該魔法方法
res=self.__list1[self.__index]
self.__index+=1
return res
以上為自定義迭代器類的機制。
下面再示例說明下,如何自定義生成器函式,因為大多數實戰場景中,使用生成器函式可能會更多一些:
def my_gene_func():
index=0
li=[1,2,3,4,5]
yield li[index]
index+=1
呼叫以上函式時,會返回乙個生成器物件,然後對該生成器物件,使用 next() 逐一返回:
gene=my_gene_func()
next(gene)
其實核心的概念還是記憶上次迭代的位置,類中直接使用 __next__ 魔法方法實現,函式中使用 yield 實現。且懷疑,類中的 __next__ 魔法方法底層也是使用 yield 來實現的。
迭代器和生成器具體應用場景,就凡是需要提公升執行效率或節約記憶體資源,且遍歷的資料是集合形式的,都可以考慮。
另外乙個小眾的使用場景,是變相實現協程的效果,即在同乙個執行緒內,實現不同任務交替執行
def mytask1():
print('task1 開始執行')
task code
yield
def mytask2():
print('task2 開始執行')
task code
yield
gene1=mytask1()
gene2=mytask2()
for i in range(100):
next(gene1)
next(gene2)
閆偉超閆偉超
yif***[email protected]個月前 (05-14)
python 菜鳥 Python3 教程
python 3 教程 python 的 3.0 版本,常被稱為 python 3000,或簡稱 py3k。相對於 python 的早期版本,這是乙個較大的公升級。為了不帶入過多的累贅,python 3.0 在設計的時候沒有考慮向下相容。python 介紹及安裝教程我們在python 2.x 版本的...
python3菜鳥教程pdf Python3 集合
本課一句話通俗話總結函式 新增元素 setx.add string tuple bool number void setx.update y z.void y z 為 list tuple dict setx.clear void setx.copy set 深拷貝 指向新的記憶體位址 刪除元素 s...
裝飾器python3菜鳥教程 Python 裝飾器
首先 需求來了 有如下幾個封裝好的函式供呼叫 現在需要在每個函式執行前進行日誌記錄 第乙個方案 修改每個函式,新增日誌記錄的 但這樣顯然不太好,存在大量的重複 可以將重複 封裝為乙個方法 第二個方案 這樣的確是比第乙個方案好多了,但是不符合開閉原則,即現有的 不要去修改,而在基礎的功能上進行二次開發...