初識Python 7 Python迭代器

2022-08-27 23:33:16 字數 3924 閱讀 1856

迭代器是訪問集合內元素的一種方式。迭代器物件從集合的第乙個元素開始訪問,直到所有的元素都被訪問一遍後結束。

迭代器不能回退,只能往前進行迭代。這並不是什麼很大的缺點,因為人們幾乎不需要在迭代途中進行回退操作。

迭代器也不是執行緒安全的,在多執行緒環境中對可變集合使用迭代器是乙個危險的操作。但如果小心謹慎,或者乾脆貫徹函式式思想堅持使用不可變的集合,那這也不是什麼大問題。

對於原生支援隨機訪問的資料結構(如tuple、list),迭代器和經典for迴圈的索引訪問相比並無優勢,反而丟失了索引值(可以使用內建函式enumerate()找回這個索引值,這是後話)。但對於無法隨機訪問的資料結構(比如set)而言,迭代器是唯一的訪問元素的方式。

迭代器的另乙個優點就是它不要求你事先準備好整個迭代過程中所有的元素。迭代器僅僅在迭代至某個元素時才計算該元素,而在這之前或之後,元素可以不存在或者被銷毀。這個特點使得它特別適合用於遍歷一些巨大的或是無限的集合,比如幾個g的檔案,或是斐波那契數列等等。這個特點被稱為延遲計算或惰性求值(lazy evaluation)。

迭代器更大的功勞是提供了乙個統一的訪問集合的介面。只要是實現了__iter__()方法的物件,就可以使用迭代器進行訪問。

建立迭代

對物件呼叫乙個iter(),就可以得到它的迭代器,

#

##語法:

iter(obj)

#乙個引數

iter(func, sentinel )

#兩個引數

如果你傳遞乙個引數給 iter() , 它會檢查你傳遞的是不是乙個序列, 如果是, 那麼很簡單:根據索引從 0 一直迭代到序列結束. 另乙個建立迭代器的方法是使用類, 我們將在第 13 章詳細介紹, 乙個實現了 __iter__() 和 next() 方法的類可以作為迭代器使用.

如果是傳遞兩個引數給 iter() , 它會重複地呼叫 func , 直到迭代器的下個值等於sentinel .

關於迭代

根本上說, 迭代器就是有乙個 next() 方法的物件, 而不是通過索引來計數. 當你或是乙個迴圈機制(例如 for 語句)需要下乙個項時, 呼叫迭代器的 next() 方法就可以獲得它. 條目全部取出後, 會引發乙個 stopiteration 異常, 這並不表示錯誤發生, 只是告訴外部呼叫者, 迭代完成.

例如 for 迴圈遍歷,這種形式的訪問清晰、簡潔、方便。這種迭代器的用法在 python 中普遍而且統一。在後台,for 語句在容器物件中呼叫 iter() 。 該函式返回乙個定義了 next() 方法的迭代器物件,它在容器中逐一訪問元素。沒有後續的元素時,next() 丟擲乙個 stopiteration 異常通知 for 語句迴圈結束。

例如:

for迴圈:

>>> for i in

'abc':

printia

bc實際執行原理:

>>> s = '

abc'

>>> it =iter(s)

>>>it

>>>it.next()'a

'>>>it.next()'b

'>>>it.next()'c

'>>>it.next()

traceback (most recent call last):

file

"", line 1, in -toplevel-it.next()

stopiteration

序列使用迭代器

>>> mytuple = (123, '

xyz', 45.67)

>>> i =iter(mytuple)

>>>i.next()

123>>>i.next()

'xyz

'>>>i.next()

45.67

>>>i.next()

traceback (most recent call last):

file

"", line 1, in

?stopiteration

字典使用迭代器

字典和檔案是另外兩個可迭代的 python 資料型別. 字典的迭代器會遍歷它的鍵(keys).語句 for eachkey in mydict.keys() 可以縮寫為 for eachkey in mydict , 例如:

>>> legends = 

...>>> for eachlegend in

legends:

...

print

'name: %s\toccupation: %s

' %eachlegend

...

print

'birth: %s\tdeath: %s\talbum: %s\n'\

... %legends[eachlegend]

...name: freud occupation: psychoanalyst

birth: 1856 death: 1939 album: 1990name: poe occupation: author

birth: 1809 death: 1849 album: 1976name: gaudi occupation: architect

birth: 1852 death: 1906 album: 1987

另外, python 還引進了三個新的內建字典方法來定義迭代:mydict.iterkeys() (通過 keys 迭代), mydict.itervalues() (通過 values 迭代), 以及 mydicit.iteritems() (通過 key/value 對來迭代).

列表解析

#

##語法:

[expr

for iter_var in iterable]

這個語句的核心是 for 迴圈, 它迭代 iterable 物件的所有條目. 前邊的 expr 應用於序列的每個成員, 最後的結果值是該表示式產生的列表. 迭代變數並不需要是表示式的一部分.

#

例如:>>> map(lambda x: x ** 2, range(6))

[0, 1, 4, 9, 16, 25]

#可以由下面的列表解析替換:

>>> [x ** 2 for x in range(6)] #

可以寫成[(x ** 2) for x in range(6)],更清楚

[0, 1, 4, 9, 16, 25]

列表解析的表示式可以取代內建的 map() 函式以及 lambda , 而且效率更高. 結合if語句,列表解析還提供了乙個擴充套件版本的語法:

[expr for iter_var in iterable if cond_expr]

這個語法在迭代時會過濾/捕獲滿足條件表示式 cond_expr 的序列成員.

#

##樣例:序列中的奇數

>>> seq = [11, 10, 9, 9, 10, 10, 9, 8, 23, 9, 7, 18, 12, 11, 12]

>>> [x for x in seq if x % 2]

[11, 9, 9, 9, 23, 9, 7, 11]

#

如下這樣乙個資料檔案 hhga.txt , 需要計算出所有非空白字元的數目:

>>> f = open('

hhga.txt

', 'r'

)>>> len([word for line in f for word in line.split()]) #

巢狀for迴圈

91

初識python教學反思 初識Python

引子 計算機程式語言如同我們的自然語言一樣,有其一套規範的語法,我們學習程式語言不過是學習它的那一套規則罷了。語言的發展史 機器語言 組合語言 c語言 寫程式時需要操作記憶體 高階語言 有虛擬機器或直譯器 隨著科技的進步以及計算機歷史的發展,程式語言也由最初晦澀的機器語言發展到了現在接近於人類自然語...

Python學習筆記( ) 初識python

閒時沒事做,就在網上隨便找關於幾種常用程式語言優缺點,顯然我被python這門特殊的語言給迷住,它在我眼中與其他的語言的最大不同在於其簡潔美所在,以及其強大各種庫的支援,它的 形式猶如我學習c語言的時老師講偽 一樣,看著非常舒服,功能很強大,學習起來也很簡單,它的應用也很廣泛,很多科學計算都選擇它,...

Python學習之路 初識Python

python的創始人是吉多 範羅蘇姆 guido van rossum 在中國被親切地稱為 龜叔 荷蘭人。他是一位數學家,同時也傾向於做計算機的工作,熱衷於程式設計。guido曾使用過pascal c fortran等,這些語言的設計原則是讓機器能更快地執行。以c語言為例,用c語言實現乙個功能需要編...