列式容器有乙個共同的特性,它們都支援使用 for 迴圈遍歷儲存的元素,都是可迭代的,因此它們又有乙個別稱,即迭代器。從字面來理解,迭代器指的就是支援迭代的容器,更確切的說,是支援迭代的容器類物件,這裡的容器可以是列表、元組等這些 python 提供的基礎容器,也可以是自定義的容器類物件,只要該容器支援迭代即可。
如果要自定義實現乙個迭代器,則類中必須實現如下 2 個方法:
__iter__(self):該方法返回乙個迭代器(iterator)。
除此之外,python 內建的 iter() 函式也會返回乙個迭代器,該函式的語法格式如下:
iter(obj[, sentinel])其中,obj 必須是乙個可迭代的容器物件,而 sentinel 作為可選引數,如果使用此引數,要求 obj 必須是乙個可呼叫物件。可呼叫物件,指的是該類的例項物件可以像函式那樣,直接以「物件名()」的形式被使用。通過在類中新增 __call__() 方法,就可以將該類的例項物件程式設計可呼叫物件。有關 __call__() 方法,我們常用的是僅有 1 個引數的 iter() 函式,通過傳入乙個可迭代的容器物件,我們可以獲得乙個迭代器,通過呼叫該迭代器中的 __next__() 方法即可實現迭代。另外,也可以使用 next() 內建函式來迭代,即 next(myiter),和 __next__() 方法是完全一樣的。
從程式的執行結果可以看出,當迭代完儲存的所有元素之後,如果繼續迭代,則 __next__() 方法會丟擲 stopiteration 異常。這裡介紹 iter() 函式第 2 個引數的作用,如果使用該引數,則要求第乙個 obj 引數必須傳入可呼叫物件(可以不支援迭代),這樣當使用返回的迭代器呼叫 __next__() 方法時,它會通過執行 obj() 呼叫 __call__() 方法,如果該方法的返回值和第 2 個引數值相同,則輸出 stopinteration 異常;反之,則輸出 __call__() 方法的返回值。迭代器本身是乙個底層的特性和概念,在程式中並不常用,但它為生成器這一更有趣的特性提供了基礎。
在使用該容器迭代一組資料時,必須事先將所有資料儲存到容器中,才能開始迭代;而生成器卻不同,它可以實現在迭代的同時生成元素。也就是說,對於可以用某種演算法推算得到的多個資料,生成器並不會一次性生成它們,而是什麼時候需要,才什麼時候生成。不僅如此,生成器的建立方式也比迭代器簡單很多,大體分為以下 2 步:
定義乙個以 yield 關鍵字標識返回值的函式;
呼叫剛剛建立的函式,即可建立乙個生成器。
要想使生成器函式得以執行,或者想使執行完 yield 語句立即暫停的程式得以繼續執行,有以下 2 種方式:
通過生成器(上面程式中的 num)呼叫 next() 內建函式或者 __next__() 方法;
通過 for 迴圈遍歷生成器。
注意,在 python 2.x 版本中不能使用 __next__() 方法,可以使用 next() 內建函式,另外生成器還有 next() 方法(即以 num.next() 的方式呼叫)。除此之外,還可以使用 list() 函式和 tuple() 函式,直接將生成器能生成的所有值儲存成列表或者元組的形式。相比迭代器,生成器最明顯的優勢就是節省記憶體空間,即它不會一次性生成所有的資料,而是什麼時候需要,什麼時候生成。
doraemon的python 迭代器與生成器
6.9.1迭代器的定義 自己不用寫,只需要學會用 迭代器 對可迭代物件中的元素進行逐一獲取,表象 具有 next 方法且每次呼叫都獲取可迭代物件中的元素 從前到後乙個個獲取 迭代器想要獲取每個值,就必須反覆執行 v1 11,22,33,44 列表轉化成迭代器 v2 iter v1 result v2...
Python學習 迭代器
含義迭代的意思類似於迴圈,每一次重複的過程被稱為一次迭代的過程,而每一次迭代得到的結果會被用來作為下一次迭代的初始值 提供迭代方法的容器稱為迭代器,常用的迭代器 列表 元組 字串 字典。示例 1 字串 字串就是乙個容器,同時也是乙個迭代器,for 語句的作用就是觸發這個迭代器的迭代功能,每次從容器裡...
Python 迭代物件與迭代器
可迭代物件 iterable 可以直接作用於for迴圈的物件統稱為可迭代物件。可以用isinstance 去判斷乙個物件是否是可迭代物件 iterable 可以直接作用於for的資料型別一般分兩種 1 集合資料型別,如list tuple dict set string 2 generator,包括...