色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術(shù)文章
文章詳情頁

python學(xué)習(xí)之可迭代對(duì)象、迭代器、生成器

瀏覽:3日期:2022-06-23 13:10:10
Iterable ? 可迭代對(duì)象

能夠逐一返回其成員項(xiàng)的對(duì)象。 可迭代對(duì)象的例子包括所有序列類型 (例如 list, str 和 tuple) 以及某些非序列類型例如 dict, 文件對(duì)象以及定義了__iter__()方法或是實(shí)現(xiàn)了序列語義的__getitem__() 方法的任意自定義類對(duì)象。

可迭代對(duì)象可用于 for 循環(huán)以及許多其他需要一個(gè)序列的地方(zip()、map() …)。當(dāng)一個(gè)可迭代對(duì)象作為參數(shù)傳給內(nèi)置函數(shù) iter() 時(shí),它會(huì)返回該對(duì)象的迭代器。這種迭代器適用于對(duì)值集合的一次性遍歷。在使用可迭代對(duì)象時(shí),你通常不需要調(diào)用 iter() 或者自己處理迭代器對(duì)象。for 語句會(huì)為你自動(dòng)處理那些操作,創(chuàng)建一個(gè)臨時(shí)的未命名變量用來在循環(huán)期間保存迭代器

判斷對(duì)象是否為可迭代對(duì)象:可以使用isinstance與collections模塊的Iterable類型

#分別對(duì)python的各種數(shù)據(jù)類型進(jìn)行判斷from collections import Iterablea = 123isinstance(a,Iterable) >>> Falsea = ’abc’isinstance(a,Iterable) >>> Truea = (1,2,3)isinstance(a,Iterable) >>> Truea = [1,2,3]isinstance(a,Iterable) >>> Truea = {’name’:’wwl’,’age’:24,’sex’:’男’}isinstance(a,Iterable) >>> Truea = {1,2,3}isinstance(a,Iterable) >>> True#可以看到字符串,元組,列表,字典,集合是可迭代對(duì)象;數(shù)字不是

通過上面我們得到可迭代對(duì)象有:字符串,元組,列表,字典,集合我們可以使用內(nèi)置的dir()函數(shù)對(duì)python數(shù)據(jù)類型進(jìn)行操作,會(huì)發(fā)現(xiàn)可迭代對(duì)象(str,tuple,list,dict,set)均實(shí)現(xiàn)了__iter__方法,而不是可迭代對(duì)象的int類型則沒有__iter__方法

dir(int)[’...(省略)’, ’__index__’, ’__init__’, ’__init_subclass__’, ’__int__’, ’__invert__’,’...(省略)’ ]dir(str)[’...(省略)’, ’__iter__’, ’...(省略)’]dir(tuple)[’...(省略)’, ’__iter__’, ’...(省略)’]dir(list)[’...(省略)’, ’__iter__’, ’...(省略)’]dir(dict)[’...(省略)’, ’__iter__’, ’...(省略)’]dir(set)[’...(省略)’, ’__iter__’, ’...(省略)’]

到底是不是__iter__方法決定對(duì)象是否是可迭代對(duì)象呢?我們可以驗(yàn)證一下:

#自定義兩個(gè)類:A類和B類,其中B類實(shí)現(xiàn)__iter__方法,A類則沒有from collections import Iterableclass A():... def __init__(self):... pass... class B(): def __init__(self): pass def __iter__(self): return self#生成兩個(gè)實(shí)例化對(duì)象:a和b a = A()b = B()#可以看到實(shí)現(xiàn)__iter__方法的b對(duì)象是可迭代對(duì)象,而a對(duì)象不是isinstance(a,Iterable) >>> Falseisinstance(b,Iterable) >>> True特殊情況:實(shí)現(xiàn)了__getitem__方法的序列也是可迭代對(duì)象

sequence ? 序列一種 iterable,它支持通過__getitem__() 特殊方法來使用整數(shù)索引進(jìn)行高效的元素訪問,并定義了一個(gè)返回序列長(zhǎng)度的__len__() 方法。內(nèi)置的序列類型有l(wèi)ist、str、tuple 和 bytes。注意雖然 dict 也支持__getitem__() 和__len__(),但它被認(rèn)為屬于映射而非序列,因?yàn)樗檎視r(shí)使用任意的 immutable 鍵而非整數(shù)。

#自定義一個(gè)實(shí)現(xiàn)__getitem__方法的序列class A(): def __init__(self,*args): self.args = args def __getitem__(self,i): return self.args[i] def __len__(self): num = 0 while True: try: self.args[num] num += 1 except: return num a = A(1,2,3,’ss’,’dd’)#可以看到實(shí)例化后的對(duì)象是可以通過for...in進(jìn)行循環(huán)訪問的,表示其是可迭代對(duì)象。for i in range(len(a)): print(a[i]) >>> 1 2 3 ss dd #我們使用collections模塊的Iterable進(jìn)行判斷:from collections import Iterable,Iteratorisinstance(a,Iterable) >>> False#結(jié)果出乎意料,判定對(duì)象a不是可迭代對(duì)象,為什么呢?#因?yàn)閏ollections模塊的Iterable自動(dòng)忽略了對(duì)象的__getitem__方法,只根據(jù)對(duì)象是否有__iter__方法進(jìn)行判斷。一般來說,標(biāo)準(zhǔn)的序列均實(shí)現(xiàn)了__iter__方法。#既然上面方法無法判斷具有__getitem__方法的序列是否是可迭代對(duì)象,那又該如何判斷呢?#可以使用iter()函數(shù),如果不報(bào)錯(cuò),說明是可迭代對(duì)象,報(bào)錯(cuò)就不是b = iter(a)isinstance(b,Iterable) >>> Trueisinstance(b,Iterator) >>> TrueIterator ? 迭代器:內(nèi)部實(shí)現(xiàn)__iter__和__next__方法的對(duì)象

用來表示一連串?dāng)?shù)據(jù)流的對(duì)象。重復(fù)調(diào)用迭代器的 next() 方法(或?qū)⑵鋫鹘o內(nèi)置函數(shù) next())將逐個(gè)返回流中的項(xiàng)。當(dāng)沒有數(shù)據(jù)可用時(shí)則將引發(fā) StopIteration 異常。到這時(shí)迭代器對(duì)象中的數(shù)據(jù)項(xiàng)已耗盡,繼續(xù)調(diào)用其 next() 方法只會(huì)再次引發(fā) StopIteration 異常。迭代器必須具有 iter() 方法用來返回該迭代器對(duì)象自身,因此迭代器必定也是可迭代對(duì)象,可被用于其他可迭代對(duì)象適用的大部分場(chǎng)合。一個(gè)顯著的例外是那些會(huì)多次重復(fù)訪問迭代項(xiàng)的代碼。容器對(duì)象(例如 list)在你每次向其傳入 iter() 函數(shù)或是在 for 循環(huán)中使用它時(shí)都會(huì)產(chǎn)生一個(gè)新的迭代器。如果在此情況下你嘗試用迭代器則會(huì)返回在之前迭代過程中被耗盡的同一迭代器對(duì)象,使其看起來就像是一個(gè)空容器。

判斷對(duì)象是否為迭代器:使用isinstance與collections模塊的Iterator類型

from collections import Iterable,Iterator#創(chuàng)建兩個(gè)類:B類和C類,B類實(shí)現(xiàn)了__iter__方法,C類實(shí)現(xiàn)了__iter__和__next__方法class B(): def __init__(self): pass def __iter__(self): return self class C(): def __init__(self): pass def __iter__(self): return self def __next__(self): return 123#實(shí)例化兩個(gè)對(duì)象 b = B()c = C()#可以看到b對(duì)象是可迭代對(duì)象,卻不是迭代器;c對(duì)象既是可迭代對(duì)象,又是迭代器.isinstance(b,Iterable) >>> Trueisinstance(b,Iterator) >>> Falseisinstance(c,Iterator) >>> Trueisinstance(c,Iterable) >>> True生成迭代器有兩種方法:1.使用內(nèi)置的iter(object[, sentinel])函數(shù);

返回迭代器對(duì)象。根據(jù)第二個(gè)參數(shù)的存在,第一個(gè)參數(shù)的解釋非常不同。如果沒有第二個(gè)參數(shù),對(duì)象必須是支持迭代協(xié)議的集合對(duì)象(iter()方法),或者必須支持序列協(xié)議(getitem()方法,整數(shù)參數(shù)從0開始)。如果它不支持這兩個(gè)協(xié)議中的任何一個(gè),則會(huì)引發(fā)TypeError。如果給出了第二個(gè)參數(shù)sentinel,那么object必須是可調(diào)用的對(duì)象。在這種情況下創(chuàng)建的迭代器將調(diào)用對(duì)象,每次調(diào)用它的__next __()方法時(shí)都不帶參數(shù);如果返回的值等于sentinel,則將引發(fā)StopIteration,否則將返回該值。

iter()的第一種形式:不帶第二個(gè)參數(shù),第一個(gè)參數(shù)表示可迭代對(duì)象(具有__iter__()方法或者_(dá)_getitem__()方法)

#自定義兩個(gè)類,一個(gè)支持__iter__()方法,一個(gè)支持__getitem__()方法#1.定義一個(gè)支持迭代協(xié)議的集合對(duì)象:class A(): def __init__(self): pass def __iter__(self): self.num = 0 return self def __next__(self): if self.num < 10: N = self.num self.num += 1 return N else: raise StopIteration a = A()b = iter(a)from collections import Iterable,Iterator#由于A類中我們定義的__iter__()函數(shù)是返回自己,同時(shí)定義了自身的__next__()方法,所以對(duì)象a既是可迭代對(duì)象,又是迭代器。isinstance(a,Iterable) >>> Trueisinstance(a,Iterator) >>> True#同時(shí)我們可以看到對(duì)象a經(jīng)過iter()方法后生成的b對(duì)象是迭代器。isinstance(b,Iterator) >>> Trueisinstance(b,Iterable) >>> True#定義一個(gè)支持序列協(xié)議的對(duì)象class B(): def __init__(self,*args): self.args = args def __getitem__(self,i): return self.args[i] def __len__(self): num = 0 while True: try: self.args[num] num += 1 except: return numb = B()c = iter(b)#由于b對(duì)象定義的是__getitem__()方法,所以無法使用collections模塊對(duì)b對(duì)象進(jìn)行判斷。#這里我們只對(duì)使用了iter()方法后生成的c對(duì)象進(jìn)行判斷isinstance(c,Iterable) >>> Trueisinstance(c,Iterator) >>> True#可以看到使用了iter()方法后生成的對(duì)象c是迭代器

iter()的第二種形式:帶第二個(gè)參數(shù),第一個(gè)參數(shù)表示可調(diào)用對(duì)象,當(dāng)返回值為第二個(gè)參數(shù)時(shí),觸發(fā)StopIteration

class A(): def __init__(self): self.num = 1 def __call__(self): x = self.num self.num += 1 return x a = A()b = iter(a,5)from collections import Iterable,Iterator#我們可以看到a對(duì)象既不是可迭代對(duì)象也不是迭代器,但通過iter()方法返回的對(duì)象b確實(shí)迭代器isinstance(a,Iterable) >>> Falseisinstance(a,Iterator) >>> Falseisinstance(b,Iterator) >>> Trueisinstance(b,Iterable) >>> True#通過for...in循環(huán)遍歷打印(每次循環(huán)都調(diào)用__call__()方法,直至返回值等于5,觸發(fā)StopIteration停止迭代)for i in b: print(i) >>> 1 2 3 4 #iter()的第二種形式的一個(gè)有用的應(yīng)用是構(gòu)建塊讀取器。例如,從二進(jìn)制數(shù)據(jù)庫(kù)文件中讀取固定寬度的塊,直到到達(dá)文件結(jié)尾:from functools import partialwith open(’mydata.db’, ’rb’) as f: for block in iter(partial(f.read, 64), b’’): process_block(block)2.直接調(diào)用可迭代對(duì)象的__iter__方法;

#定義__iter__()方法,可以返回自己,但自己要定義__next__()方法;也可以返回其他對(duì)象的迭代器#第一種:返回自身,同時(shí)定義自身的__next__()方法class A(): def __init__(self): pass def __iter__(self): self.num = 0 return self def __next__(self): if self.num < 10: N = self.num self.num += 1 return N else: raise StopIterationa = A()b = a.__iter__()from collections import Iterable,Iterator#由于A類中我們定義的__iter__()函數(shù)是返回自己,同時(shí)定義了自身的__next__()方法,所以對(duì)象a既是可迭代對(duì)象,又是迭代器。isinstance(a,Iterable) >>> Trueisinstance(a,Iterator) >>> True#同時(shí)我們可以看到對(duì)象a經(jīng)過iter()方法后生成的b對(duì)象是迭代器。isinstance(b,Iterable) >>> Trueisinstance(b,Iterator) >>> True#第二種:返回其他對(duì)象的迭代器class A(): def __init__(self): pass def __iter__(self): self.num = 0 return bclass B(A): def __next__(self): if self.num < 10: N = self.num self.num += 1 return N else: raise StopIteration #實(shí)例化兩個(gè)對(duì)象:a和b,當(dāng)調(diào)用對(duì)象a的__iter__()方法時(shí),返回對(duì)象b,B繼承于A類,所以b對(duì)象是一個(gè)迭代器。a = A()b = B()#調(diào)用a的__iter__()方法c = a.__iter__()from collections import Iterable,Iterator#由于對(duì)象a不具備__next__()方法,因此僅僅是一個(gè)可迭代對(duì)象isinstance(a,Iterable) >>> Trueisinstance(a,Iterator) >>> False#但是調(diào)用對(duì)象a的__iter()方法生成的c,同時(shí)具備__iter__()和__next__()方法,是一個(gè)迭代器。isinstance(c,Iterable) >>> Trueisinstance(c,Iterator) >>> True

上面兩種方式表示可以生成迭代器,但并不是使用這兩個(gè)函數(shù)就一定生成迭代器,這取決于運(yùn)行這兩個(gè)函數(shù)返回的是什么

#iter()函數(shù):其運(yùn)行機(jī)制是尋找對(duì)象中的__iter__()方法,運(yùn)行并返回結(jié)果,如果__iter__()方法返回的不是迭代器,則此方法會(huì)報(bào)錯(cuò);如果沒有此方法,則尋找__getitem__()方法。class A(): def __init__(self): pass def __iter__(self): return 1 #我們知道數(shù)字1不是迭代器,此函數(shù)返回的是一個(gè)非迭代器 a = A()b = iter(a)Traceback (most recent call last): File '<input>', line 10, in <module>TypeError: iter() returned non-iterator of type ’int’#直接調(diào)用__iter__()方法:如果想通過調(diào)用此方法生成迭代器,只能定義在此函數(shù)下返回一個(gè)迭代器;如果定義返回的不是迭代器,調(diào)用此方法是不會(huì)生成迭代器的。class A(): def __init__(self): pass def __iter__(self): return 1 a = A()#直接調(diào)用__iter__()方法b = a.__iter__()#我們可以看到返回的是1,而不是迭代器,只有當(dāng)你定義返回迭代器時(shí),調(diào)用此方法才會(huì)返回迭代器print(b) >>> 1判斷對(duì)象是否是可迭代對(duì)象:1.collections模塊的Iterable類型,使用isinstance()判斷(此方法不太準(zhǔn))

#我們定義一個(gè)類:具有__iter__()方法,但返回的不是迭代器class A(): def __init__(self): pass def __iter__(self): return 1 a = A()from collections import Iterable#我們使用isinstance()結(jié)合collections看一下:會(huì)發(fā)現(xiàn)此方法認(rèn)為他是一個(gè)可迭代對(duì)象isinstance(a,Iterable) >>> True#我們使用for...in進(jìn)行循環(huán)訪問,發(fā)現(xiàn)并不能for i in a: print(i) Traceback (most recent call last): File '<input>', line 1, in <module>TypeError: iter() returned non-iterator of type ’int’#接下來,我們?cè)俣x一個(gè)類:具有__iter__()方法和__next__()方法,但返回的不是迭代器class A(): def __init__(self): pass def __iter__(self): pass def __next__(self): passa = A()from collections import Iterator#我們使用isinstance()結(jié)合collections看一下:會(huì)發(fā)現(xiàn)此方法認(rèn)為他是一個(gè)迭代器isinstance(a,Iterator) >>> True#我們使用for...in進(jìn)行循環(huán)訪問,發(fā)現(xiàn)并不能for i in a: print(a) Traceback (most recent call last): File '<input>', line 1, in <module>TypeError: iter() returned non-iterator of type ’NoneType’2.使用iter()內(nèi)置函數(shù)進(jìn)行判斷:

class A(): def __init__(self): pass def __iter__(self): return 1 a = A()#使用iter()函數(shù)如果報(bào)錯(cuò),則不是可迭代對(duì)象,如果不報(bào)錯(cuò),則是可迭代對(duì)象b = iter(a)Traceback (most recent call last): File '<input>', line 1, in <module>TypeError: iter() returned non-iterator of type ’int’3.使用for…in方法進(jìn)行遍歷,如果可以遍歷,即為可迭代對(duì)象

#for...in循環(huán)的實(shí)質(zhì)是:先調(diào)用對(duì)象的__iter__()方法,返回一個(gè)迭代器,然后不斷的調(diào)用迭代器的__next__()方法。class A(): def __init__(self): pass def __iter__(self): self.num = 0 return self def __next__(self): if self.num < 10: N = self.num self.num += 1 return N else: raise StopIterationa = A()for i in a: print(i) >>> 0 1 2 3 4 5 6 7 8 9#等同于:先調(diào)用對(duì)象的__iter__()方法,返回一個(gè)迭代器,然后不斷的調(diào)用迭代器的__next__()方法,調(diào)用完返回StopIteration,結(jié)束迭代b = iter(a)while True: try: next(b) except: raise StopIteration0 1 2 3 4 5 6 7 8 9Traceback (most recent call last): File '<stdin>', line 3, in <module> File '<stdin>', line 13, in __next__StopIteration

經(jīng)過上面三種判斷方法的分析,我們可以得出一些結(jié)論:1.collection模塊的Iterable,Iterator類型并不能準(zhǔn)確的判斷對(duì)象是否是可迭代對(duì)象,或者是否是迭代器,它的判斷原理只是檢查對(duì)象內(nèi)部是否定義了__iter__()和__next__()方法,而不注重這兩個(gè)函數(shù)所返回的內(nèi)容。2.相比于collections模塊,iter()函數(shù)則與其不同,它更注重__iter__()函數(shù)返回的內(nèi)容,如果返回的是迭代器,則iter()的參數(shù)即為可迭代對(duì)象,否則,使用iter()函數(shù)會(huì)報(bào)錯(cuò)。此方法比較常用,也相對(duì)好用。3.for…in循環(huán)方法,也可以用來判斷對(duì)象是否是可迭代對(duì)象,此方法本質(zhì)就是調(diào)用對(duì)象__iter__()和__next__()方法,他同樣注重函數(shù)的返回內(nèi)容。

經(jīng)過以上種種實(shí)例的分析,我們發(fā)現(xiàn)僅僅具有__iter__()和__next__方法并不能算真正意義上的可迭代對(duì)象或者迭代器,如果不注重方法返回的內(nèi)容,實(shí)例化的對(duì)象卻不能進(jìn)行迭代訪問,又怎么能稱為可迭代對(duì)象和迭代器呢?因此我們?cè)谶@里對(duì)可迭代對(duì)象和迭代器進(jìn)行重新定義

類型 定義 判斷方法 - 可迭代對(duì)象 內(nèi)部定義了__iter__()方法且返回迭代器,可以返回自己也可以返回其他迭代器,如果返回自己,則自己還必須定義__next__()方法;也可以是定義__getitem__()方法的序列,整數(shù)參數(shù)可以從0進(jìn)行索引,一般來說,標(biāo)準(zhǔn)的序列均定義了__iter__()方法,所以序列也是符合可迭代對(duì)象的要求的 可以使用iter()方法進(jìn)行判斷,將對(duì)象作為參數(shù)輸入,如果不報(bào)錯(cuò)則為可迭代對(duì)象;反之,則不是。除此之外,使用for循環(huán)進(jìn)行遍歷,也可以識(shí)別;還有就是能夠看到對(duì)象的源碼,直接根據(jù)定義進(jìn)行判斷 迭代器 內(nèi)部定義了__iter__()方法,與可迭代對(duì)象不同的是,對(duì)象的__iter__()方法必須返回的是自己,同時(shí)自己定義了__next__()方法 如果是迭代器,是可以調(diào)用__next__()方法的,調(diào)用所有元素后,拋出StopIteration錯(cuò)誤;判斷Iterator最好是能夠看到源碼,直接根據(jù)定義判斷。 generator ? 生成器:

生成器是一個(gè)用于創(chuàng)建迭代器的簡(jiǎn)單而強(qiáng)大的工具。它們的寫法類似于標(biāo)準(zhǔn)的函數(shù),但當(dāng)它們要返回?cái)?shù)據(jù)時(shí)會(huì)使用yield 語句。每次在生成器上調(diào)用next() 時(shí),它會(huì)從上次離開的位置恢復(fù)執(zhí)行(它會(huì)記住上次執(zhí)行語句時(shí)的所有數(shù)據(jù)值)。

可以用生成器來完成的操作同樣可以用基于類的迭代器來完成。 但生成器的寫法更為緊湊,因?yàn)樗鼤?huì)自動(dòng)創(chuàng)建 iter() 和 next() 方法。

另一個(gè)關(guān)鍵特性在于局部變量和執(zhí)行狀態(tài)會(huì)在每次調(diào)用之間自動(dòng)保存。 這使得該函數(shù)相比使用 self.index 和 self.data 這種實(shí)例變量的方式更易編寫且更為清晰。

除了會(huì)自動(dòng)創(chuàng)建方法和保存程序狀態(tài),當(dāng)生成器終結(jié)時(shí),它們還會(huì)自動(dòng)引發(fā) StopIteration。 這些特性結(jié)合在一起,使得創(chuàng)建迭代器能與編寫常規(guī)函數(shù)一樣容易。

def A(): yield 1 yield 2 a = A()print(a)#可以看出a顯示的是一個(gè)生成器對(duì)象<generator object A at 0x7f4f94409eb8>#我們使用dir()函數(shù)看一下生成器的方法:dir(a)[’省略’, ’__iter__’, ’省略’, ’__next__’, ’send’, ’throw’,’省略’]#可以看到生成器里面自動(dòng)完成了對(duì)__iter__()和__next__()方法的定義#我們調(diào)用對(duì)象的__iter__()方法print(iter(a)) >>> <generator object A at 0x7f4f94409eb8>print(a) >>> <generator object A at 0x7f4f94409eb8>#可以看到,調(diào)用__iter__()方法,返回的是對(duì)象自己#我們調(diào)用對(duì)象的__next__()方法next(a) >>> 1#可以看到,再次調(diào)用next()方法,是在上次的基礎(chǔ)上繼續(xù)運(yùn)行的,返回的是2,而不是像普通函數(shù)一樣,從頭開始重新運(yùn)行next(a) >>> 2next(a)Traceback (most recent call last): File '<stdin>', line 1, in <module>StopIteration#可以看到生成器a調(diào)用next()方法后生成下一個(gè)元素,同時(shí)當(dāng)元素耗盡時(shí),拋出StopIteration錯(cuò)誤,這和迭代器完全相似#生成器完全符合迭代器的要求,所以生成器也屬于迭代器

除了定義一個(gè)yield函數(shù)外,還可以利用推導(dǎo)式生成一個(gè)生成器

#一般的推導(dǎo)式有列表推導(dǎo)式和字典推導(dǎo)式,與兩者不同,生成器的推導(dǎo)式是寫在小括號(hào)中的,而且只能是比較簡(jiǎn)單的生成器,比較復(fù)雜的生成器一般是寫成yield函數(shù)的形式.a = (i for i in range(5))print(a)<generator object <genexpr> at 0x03CFDE28> 類型 定義 判斷方法 生成器 使用yield的函數(shù),或者類似(i for i in range(5))這樣的推導(dǎo)式,自動(dòng)實(shí)現(xiàn)__iter__()和__next__()方法 根據(jù)定義判斷

1.生成器是一種特殊的迭代器,其內(nèi)部自動(dòng)實(shí)現(xiàn)__iter__()和__next__()方法,可用for循環(huán)遍歷輸出;2.迭代器一定是可迭代對(duì)象,但可迭代對(duì)象不一定是迭代器。

迭代器存在的意義:

在說明迭代器之前,我們需要引入一個(gè)容器的概念。什么是容器?容器是眾多對(duì)象(在python中對(duì)象的抽象是類class)的集合,根據(jù)存儲(chǔ)方式不同,python可分為四種容器:

列表(list):對(duì)象以隊(duì)列方式進(jìn)行存儲(chǔ) 元組(tuple):對(duì)象以隊(duì)列方式進(jìn)行存儲(chǔ),和列表一樣,只是存儲(chǔ)數(shù)據(jù)后,不可更改, 集合(set):對(duì)象以無序的方式進(jìn)行存儲(chǔ) 字典(dict):對(duì)象以鍵值對(duì)映射的方式存儲(chǔ)數(shù)據(jù)

在編程中,最常見的操作就是從這些容器中拿出數(shù)據(jù)。而容器一般是不具備取出數(shù)據(jù)的功能的。我們平時(shí)取出數(shù)據(jù)的操作實(shí)際上是先經(jīng)過__iter__()方法轉(zhuǎn)為迭代器,之后再通過__next__()方法拿取的(參考for循環(huán),map(),filter())。可以說迭代器賦予了容器取出數(shù)據(jù)的能力,但迭代器每次調(diào)用__next__()方法只能取出一個(gè)數(shù)據(jù),這種方法顯然是很笨拙的,于是引入for循環(huán),每次循環(huán)自動(dòng)調(diào)用__next__()方法,這使得訪問容器中的對(duì)象變得十分方便。

個(gè)人理解:迭代器的存在類似指針。

迭代器具有__iter__()方法就好比具備存放指針的資格,而__next__()方法,表示指針調(diào)度的規(guī)則。每次訪問容器中的元素,首先調(diào)用__iter__()方法在容器元素頭部放一個(gè)指針,此指針不指向任何元素,位于所有元素前面,為待操作狀態(tài),隨時(shí)準(zhǔn)備被調(diào)用。然后通過__next__()方法制定的規(guī)則來調(diào)度這個(gè)指針,使其指向不同的對(duì)象,指針?biāo)钢幈闶撬L問對(duì)象。此指針默認(rèn)有一些屬性:只能向前,不能回退,當(dāng)沒有元素時(shí),拋出StopIteration,過程結(jié)束。

python學(xué)習(xí)之可迭代對(duì)象、迭代器、生成器

使用迭代器一個(gè)明顯的優(yōu)勢(shì)是:減少內(nèi)存占用

不使用迭代器:如果我們想訪問一個(gè)容器中的所有元素,就需要將所有的元素都加載到內(nèi)存中,然后一次性打印,對(duì)于少量元素來說,這無關(guān)緊要,但當(dāng)數(shù)據(jù)量非常大時(shí),這種做法將占用很大的內(nèi)存,影響程序性能。使用迭代器:我們?cè)L問一個(gè)容器中的所有元素,不會(huì)將所有元素都加載出來,而是一個(gè)一個(gè)的加載,然后打印,這樣會(huì)極大的減少內(nèi)存的占用。

生成器存在的意義:

生成器的存在,給我更多的感受是:簡(jiǎn)化迭代器的生成。我們只需使用yield關(guān)鍵字,將數(shù)據(jù)處理的邏輯寫出,對(duì)象內(nèi)部將自動(dòng)完成對(duì)__iter__()和__next__()方法的定義,使我們不用再耗費(fèi)精力處理實(shí)例變量,以及自己定義__iter__()和__next__()方法。

特性:

1.生成器中的成員并不存在,使用一個(gè)成員立刻用yield生成一個(gè)成員(按需計(jì)算)2.生成器很節(jié)省內(nèi)存,因?yàn)槭橇⒖躺傻模院馁M(fèi)CPU進(jìn)行計(jì)算;

到此這篇關(guān)于python學(xué)習(xí)之可迭代對(duì)象、迭代器、生成器的文章就介紹到這了,更多相關(guān)python可迭代對(duì)象、迭代器、生成器內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Python 編程
相關(guān)文章:
主站蜘蛛池模板: 久久久久琪琪去精品色村长 | 国内精品久久久久久中文字幕 | 国产偷国产偷亚洲高清在线 | 最新在线步兵区 | gay毛片| 欧美a一级 | 欧美另类视频在线观看 | 亚洲精品久久久久久久网站 | 国产精品久久久免费视频 | 完整日本特级毛片 | 久久成人18免费 | 久久99精品久久久久久青青91 | 国产美女一级毛片 | 国产美女午夜精品福利视频 | 国产精品漂亮美女在线观看 | 久久99亚洲精品久久久久 | 亚洲成a人片在线观看中文 亚洲成a人片在线观看中文!!! | 国产成人精品在线观看 | 久久经典免费视频 | 最新国产区 | 亚洲性无码av在线 | 精品一区二区三区亚洲 | 欧美另类性视频在线看 | 97在线观看完整免费 | 久色tv| 午夜爽爽爽男女免费观看hd | 国产精品亚洲欧美日韩久久 | 97免费在线 | a级毛片在线视频免费观看 a级免费 | 一级毛片免费在线播放 | 男女性高爱潮免费的国产 | 99国产在线 | 精品三级网站 | 亚洲三级在线视频 | 97精品国产91久久久久久 | 日本三级香港三级少妇 | 日韩精品亚洲专区在线观看 | 国产一区二区成人 | 在线成人欧美 | 欧洲性大片xxxxx久久久 | 岛国搬运工最新网地址 |