一、迭代器
我們知道 for 循環(huán)可以用于 Python 中的任何序列類型,實(shí)際上 for 循環(huán)可用于Python 中的任何可迭代類型。對(duì)于 Python 中所有會(huì)從左至右掃描對(duì)象的迭代工具而言都是如此,這些迭代工具包括了 for 循環(huán)、列表解析、in 成員關(guān)系測(cè)試以及 map() 內(nèi)置函數(shù)等,他們都支持任何的可迭代類型。
”可迭代對(duì)象“ 的概念在 Python 中基本上和序列概念是一樣的:如果對(duì)象是實(shí)際保存的序列,或者可以在迭代工具環(huán)境中(例如,for循環(huán))一次產(chǎn)生一個(gè)結(jié)果的對(duì)象,就看做這個(gè)對(duì)象是可迭代的。總之,可迭代對(duì)象包括實(shí)際序列和按照需求而計(jì)算的虛擬序列(比如:range對(duì)象 和 生成器函數(shù))。
1、迭代協(xié)議: next()
文件對(duì)象有一個(gè)方法 __next__() ,每次調(diào)用時(shí),就會(huì)返回文件的下一行,到達(dá)文件末尾時(shí), __next__() 會(huì)引發(fā)內(nèi)置的 StopInteration 異常。
這個(gè)接口就是Python中的迭代協(xié)議:有一個(gè) __next__() 方法的對(duì)象在迭代工具的依次迭代中會(huì)依次的前進(jìn)到下一個(gè)結(jié)果,而在一系列結(jié)果的末尾時(shí),則會(huì)引發(fā)StopInteration 異常。在Python中,任何這類對(duì)象都認(rèn)為是可迭代的。任何這類對(duì)象也能以 for 循環(huán)或其他迭代工具遍歷,因?yàn)樗械牡ぞ邇?nèi)部工作起來都是在每次迭代中調(diào)用可迭代對(duì)象的 __next__() 方法,并且捕捉 StopInteration 異常來確定何時(shí)離開。
所以逐行讀取文本文件的最佳方法就是根本不要去讀取,而是讓 for 循環(huán)在每次迭代中自動(dòng)調(diào)用文件對(duì)象的 __next__() 方法從而前進(jìn)到下一行。這里的 print() 使用 end='' 參數(shù)來抑制自動(dòng)添加一個(gè) '\n',因?yàn)樽址呀?jīng)有一個(gè)(如果 print() 再自動(dòng)加上一個(gè),我們的輸出將會(huì)多輸出一個(gè)空行)。
上面是讀取文本文件的最佳方式,因?yàn)檫@是代碼最簡(jiǎn)單、運(yùn)行最快的方法,并且從內(nèi)存使用情況來說也是最好的。迭代器在 Python 中是以 C 語言的速度運(yùn)行的,而 while 循環(huán)則是通過 Python 虛擬機(jī)運(yùn)行 Python 字節(jié)碼的。所以我們一直建議在能夠使用 for 循環(huán)的時(shí)候都使用 for 循環(huán),因?yàn)樗褂酶奖悖\(yùn)行更高效。
2、內(nèi)置函數(shù):next() 和 iter()
為了更方便的手動(dòng)迭代可迭代對(duì)象,Python 3.0 還提供了一個(gè)內(nèi)置函數(shù) next() ,它會(huì)自動(dòng)調(diào)用一個(gè)對(duì)象的 __next__() 方法。也就是說對(duì)于一個(gè)可迭代對(duì)象,使用 next() 內(nèi)建函數(shù)調(diào)用和調(diào)用其 __next__() 方法是一樣的,但是前者要簡(jiǎn)單很多。
當(dāng) for 循環(huán)開始時(shí),會(huì)將對(duì)象傳給 iter() 內(nèi)置函數(shù),以便從可迭代對(duì)象中獲得一個(gè)迭代器,返回的對(duì)象含有需要的 __next__() 方法。
對(duì)于文件對(duì)象來說是不需要調(diào)用 iter() 函數(shù)的,因?yàn)槲募?duì)象擁有自己的迭代器。也就是說,文件對(duì)象有自己的 __next__() 方法。
列表以及很多其他的內(nèi)置對(duì)象,自身沒有 __next__() 方法,也就是沒有自身的迭代器,但是它們支持多次打開(創(chuàng)建)迭代器。對(duì)于這樣的對(duì)象,我們必須調(diào)用 iter() 函數(shù)來為他們創(chuàng)建迭代器,啟動(dòng)迭代。盡管Python的迭代工具自動(dòng)調(diào)用這些函數(shù),我們也可以使用它們來手動(dòng)地應(yīng)用迭代協(xié)議。
3、其他迭代環(huán)境
在 Python 的內(nèi)置工具集中從左至右掃描一個(gè)對(duì)象的每項(xiàng)工具都定義為在對(duì)象上使用了迭代協(xié)議。列表解析、in 成員關(guān)系測(cè)試、map() 內(nèi)置函數(shù)以及像 sorted() 和 zip() 調(diào)用這樣的內(nèi)置函數(shù)也都使用了迭代協(xié)議,所有這些都接收一個(gè)可迭代的對(duì)象。
Python還包含了各種處理迭代的其他內(nèi)置函數(shù):
- sorted() 排序,可迭代對(duì)象中的各項(xiàng);
- zip() 組合,可迭代對(duì)象中的各項(xiàng);
- enumerate() 根據(jù)相對(duì)位置來配對(duì),可迭代對(duì)象中的各項(xiàng),
- filter() 選擇一個(gè)函數(shù)為真的項(xiàng);
- reduce() 針對(duì)可迭代對(duì)象中的成對(duì)的項(xiàng)運(yùn)行一個(gè)函數(shù)。
二、Python 3.0 中的可迭代對(duì)象
Python 3.0 中的一個(gè)基本改變是,它更強(qiáng)調(diào)迭代。除了與文件和序列這樣的內(nèi)置類型相關(guān)的迭代,字典本身,以及字典的方法 keys(),values() 和 items() 都在 Python 3.0 中返回可迭代對(duì)象,就像內(nèi)置函數(shù) range()、map()、zip() 和 filter() 所做的那樣。
1、字典
在Python3.0 中,字典對(duì)象也支持創(chuàng)建自己的迭代器,在迭代環(huán)境中,會(huì)自動(dòng)一次返回一個(gè)鍵。注意: 在 Python 3.0 中字典對(duì)象是可迭代的(沒有自己的迭代器),它返回連續(xù)的鍵。因此無需直接在此環(huán)境中調(diào)用 keys() 方法,而且這樣由于中間生成了dict_keys對(duì)象,還會(huì)導(dǎo)致執(zhí)行效率的下降。
2、range() 內(nèi)置函數(shù)
它返回一個(gè)可迭代的 range 類型對(duì)象,range 對(duì)象根據(jù)需要產(chǎn)生范圍中的數(shù)字,而不是在內(nèi)存中構(gòu)建一個(gè)結(jié)果列表。在 Python 3.0 中 range 對(duì)象只支持迭代、索引以及 len() 函數(shù)。他不支持任何其他的序列操作。
3、map()、zip() 和 filter() 內(nèi)置函數(shù)
和 range() 類似,map()、zip() 和 filter() 內(nèi)置函數(shù)在 Python 3.0 中也返回可迭代對(duì)象以節(jié)約內(nèi)存空間,而不在內(nèi)存中一次性生成一個(gè)結(jié)果列表。
和 range() 不同,它們都擁有自己的迭代器——在遍歷其結(jié)果一次以后,它們就用盡了。換句話說,不能在它們的結(jié)果上擁有那些在結(jié)果中保持不同位置的多個(gè)迭代器。4、多個(gè)迭代器 VS 單個(gè)迭代器
range 對(duì)象沒有自己的迭代器(手動(dòng)迭代時(shí),我們使用 iter() ,為 range 對(duì)象生成一個(gè)迭代器),并且它支持在其結(jié)果上創(chuàng)建多個(gè)迭代器,這些迭代器會(huì)記住它們各自的位置。《Python基礎(chǔ)手冊(cè)》系列:
Python基礎(chǔ)手冊(cè) 1 —— Python語言介紹
Python基礎(chǔ)手冊(cè) 2 —— Python 環(huán)境搭建(Linux)
Python基礎(chǔ)手冊(cè) 3 —— Python解釋器
Python基礎(chǔ)手冊(cè) 4 —— 文本結(jié)構(gòu)
Python基礎(chǔ)手冊(cè) 5 —— 標(biāo)識(shí)符和關(guān)鍵字
Python基礎(chǔ)手冊(cè) 6 —— 操作符
Python基礎(chǔ)手冊(cè) 7 —— 內(nèi)建函數(shù)
Python基礎(chǔ)手冊(cè) 8 —— Python對(duì)象
Python基礎(chǔ)手冊(cè) 9 —— 數(shù)字類型
Python基礎(chǔ)手冊(cè)10 —— 序列(字符串)
Python基礎(chǔ)手冊(cè)11 —— 序列(元組&列表)
Python基礎(chǔ)手冊(cè)12 —— 序列(類型操作)
Python基礎(chǔ)手冊(cè)13 —— 映射(字典)
Python基礎(chǔ)手冊(cè)14 —— 集合
Python基礎(chǔ)手冊(cè)15 —— 解析
Python基礎(chǔ)手冊(cè)16 —— 文件
Python基礎(chǔ)手冊(cè)17 —— 簡(jiǎn)單語句
Python基礎(chǔ)手冊(cè)18 —— 復(fù)合語句(流程控制語句)
Python基礎(chǔ)手冊(cè)19 —— 迭代器
Python基礎(chǔ)手冊(cè)20 —— 生成器
Python基礎(chǔ)手冊(cè)21 —— 函數(shù)的定義
Python基礎(chǔ)手冊(cè)22 —— 函數(shù)的參數(shù)
Python基礎(chǔ)手冊(cè)23 —— 函數(shù)的調(diào)用
Python基礎(chǔ)手冊(cè)24 —— 函數(shù)中變量的作用域
Python基礎(chǔ)手冊(cè)25 —— 裝飾器
Python基礎(chǔ)手冊(cè)26 —— 錯(cuò)誤 & 異常
Python基礎(chǔ)手冊(cè)27 —— 模塊
Python基礎(chǔ)手冊(cè)28 —— 模塊的高級(jí)概念
Python基礎(chǔ)手冊(cè)29 —— 包