python3菜鳥 Python3 迭代器與生成器

2021-10-10 03:51:44 字數 1799 閱讀 2408

如教程所說,迭代器和生成器算是 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 裝飾器

首先 需求來了 有如下幾個封裝好的函式供呼叫 現在需要在每個函式執行前進行日誌記錄 第乙個方案 修改每個函式,新增日誌記錄的 但這樣顯然不太好,存在大量的重複 可以將重複 封裝為乙個方法 第二個方案 這樣的確是比第乙個方案好多了,但是不符合開閉原則,即現有的 不要去修改,而在基礎的功能上進行二次開發...