關于python的可迭代對象、迭代器书聚、生成器的理解

最近有朋友問到python中的迭代器和生成器的區(qū)別和作用,以及如何定義和區(qū)分,今天在這里稍微總結(jié)一下滚局。

可迭代對象

定義:可迭代對象必須實現(xiàn) "_iter_()" 方法冲九。
python中的字符串、列表、元組、字典、集合檩电、文件對象等都是可迭代對象卓箫。

口說無憑魂挂,上bug...不對,上法器:可使用內(nèi)建函數(shù) isinstance 來判別。

from collections import deque
from collections.abc import Iterable, Iterator

s = "hello hmcf"
print("string is iterable? ", isinstance(s, Iterable))
print("string is iterator? ", isinstance(s, Iterator))

l = [1, 2, 3, 4]
print("list is iterable? ", isinstance(l, Iterable))
print("list is iterator? ", isinstance(l, Iterator))

d = {"city": "hangzhou", "age": 26}
print("dict is iterable? ", isinstance(d, Iterable))
print("dict is iterator? ", isinstance(d, Iterator))

t = (1, "a", 2.3, [5, 6])
print("tuple is iterable? ", isinstance(t, Iterable))
print("tuple is iterator? ", isinstance(t, Iterator))

de = deque("abcdefg")
print("deque is iterable?", isinstance(de, Iterable))
print("deque is iterator?", isinstance(de, Iterator))

結(jié)果如下:

string is iterable? True
string is iterator? False
list is iterable? True
list is iterator? False
dict is iterable? True
dict is iterator? False
tuple is iterable? True
tuple is iterator? False
deque is iterable? True
deque is iterator? False

可使用 dir() 函數(shù)來打印出來看看對象有沒有_iter_方法迫皱,也可以查看 builtins.pyi 源文件找到對應方法中的定義戏阅。

迭代器

迭代器是在可迭代對象的基礎上創(chuàng)建的訪問集合元素的一種方式。

迭代器是一個可以記住遍歷的位置的對象笆怠。

迭代器對象從集合的第一個元素開始訪問泡态,直到所有的元素被訪問完結(jié)束怔毛。迭代器只能往前不會后退,并且只會迭代一遍寄啼。

迭代器對象必須同時實現(xiàn) "_iter_()" 和 "_next_()" 方法才是迭代器副女。對于迭代器來說,"_iter_" 返回的是它自身 self,"_next_" 則是返回迭代器中的下一個值睛竣,最后沒有元素時猖吴。

字符串域仇,列表或元組對象都可用于創(chuàng)建迭代器挡逼。迭代器是可迭代對象惹骂,但可迭代對象不一定是迭代器矛物。
迭代器的優(yōu)點:每次只從對象中讀取一條數(shù)據(jù)被环,不會造成內(nèi)存的過大開銷筛欢。

至于迭代器的判斷方式,在上面的可迭代對象中已經(jīng)體現(xiàn)了么介。

for循環(huán)機制

為什么需要for循環(huán)機制壤短?因為需要去觸發(fā)、調(diào)用迭代器。字符串 、字典、列表在for循環(huán)的作用下,會生成迭代器悴侵,然后被使用逮刨。

x = 'hello'
for i in x:                    #iter_x=x.__iter__()
    print(i)                   #iter_x.__next__()
iter_l =x.__iter__()           #遵循迭代器協(xié)議,生成可迭代對象
print(iter_l.__next__())       #for循環(huán)和索引沒關系 基于迭代器機制
  • 當對象本身就是迭代器時恢总,F(xiàn)or循環(huán)工作機制:

調(diào)用 _iter_方法迎罗,返回自身self,也就是返回迭代器。不斷地調(diào)用迭代器的next()方法片仿,每次按序返回迭代器中的一個值纹安。迭代到最后沒有元素時,就拋出異常 StopIteration

  • 在可迭代對象中砂豌,for循環(huán)工作機制:

先判斷對象是否為可迭代對象(等價于判斷有沒有_iter_方法)厢岂,沒有的話直接報錯,拋出TypeError異常阳距。有的話塔粒,調(diào)用 _iter_方法,返回一個迭代器筐摘。在python內(nèi)部不斷地調(diào)用迭代器的_next_方法卒茬,每次按序返回迭代器中的一個值。迭代到最后沒有元素時咖熟,就拋出異常 StopIteration圃酵,這個異常 python 自己會處理,不會暴露給開發(fā)者馍管。

生成器

定義:邊循環(huán)邊計算的機制就稱為生成器(generator)(對象里面不是具體的內(nèi)容郭赐,而是一個產(chǎn)生數(shù)據(jù)的算法)

生成器類似于返回值為數(shù)組的一個函數(shù),這個函數(shù)可以接受參數(shù)确沸,可以被調(diào)用捌锭,但是俘陷,不同于一般的函數(shù)會一次性返回包括了所有數(shù)值的數(shù)組,生成器一次只能產(chǎn)生一個值舀锨,這樣消耗的內(nèi)存數(shù)量將大大減小岭洲,而且允許調(diào)用函數(shù)可以很快的處理前幾個返回值,因此生成器看起來像是一個函數(shù)坎匿,但是表現(xiàn)得卻像是迭代器盾剩。

python中生成器是迭代器的一種,可以被用作控制循環(huán)的迭代行為替蔬。

它有兩種形式:

  • 生成器函數(shù)
    使用yield返回值函數(shù)告私,每次調(diào)用yield會暫停,而可以使用next()函數(shù)和send()函數(shù)恢復生成器承桥。
import sys
 
def fibonacci(n): # 生成器函數(shù) - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一個迭代器驻粟,由生成器返回生成
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()
  • 生成器表達式
    只要把一個列表生成式的[]中括號改為()小括號,就創(chuàng)建一個生成器凶异∈癯牛可以直接調(diào)用next()方法依次取出內(nèi)容(取到最后會爆出錯誤,不優(yōu)雅)剩彬,另外的就是可以使用for循環(huán)來調(diào)用酷麦。
generator = (x for x in [1,4,6,7,9] if x<5)
for n in generator:
    print(n)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市喉恋,隨后出現(xiàn)的幾起案子沃饶,更是在濱河造成了極大的恐慌,老刑警劉巖轻黑,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糊肤,死亡現(xiàn)場離奇詭異,居然都是意外死亡氓鄙,警方通過查閱死者的電腦和手機馆揉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來玖详,“玉大人把介,你說我怎么就攤上這事◇” “怎么了拗踢?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長向臀。 經(jīng)常有香客問我巢墅,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任君纫,我火速辦了婚禮驯遇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蓄髓。我一直安慰自己叉庐,他們只是感情好,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布会喝。 她就那樣靜靜地躺著陡叠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪肢执。 梳的紋絲不亂的頭發(fā)上枉阵,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機與錄音预茄,去河邊找鬼兴溜。 笑死,一個胖子當著我的面吹牛耻陕,可吹牛的內(nèi)容都是我干的拙徽。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼诗宣,長吁一口氣:“原來是場噩夢啊……” “哼斋攀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起梧田,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎侧蘸,沒想到半個月后裁眯,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡讳癌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年穿稳,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片晌坤。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡逢艘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出骤菠,到底是詐尸還是另有隱情它改,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布商乎,位于F島的核電站央拖,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鲜戒,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一专控、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧遏餐,春花似錦伦腐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嗅剖,卻和暖如春辩越,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背信粮。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工黔攒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人强缘。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓督惰,卻偏偏與公主長得像,于是被迫代替她去往敵國和親旅掂。 傳聞我的和親對象是個殘疾皇子赏胚,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容