Python中的迭代器和生成器詳解
可迭代對(duì)象(Iterable)
任何實(shí)現(xiàn)了 __iter__ 方法的對(duì)象都可以稱為可迭代對(duì)象。
class Fib: def __init__(self, n): self.prev = 0 self.cur = 1 self.n = n def __iter__(self): return self fib = Fib(5) import collections print('fib is Iterable? ', isinstance(fib, collections.Iterable)) print('fib is Iterator? ', isinstance(fib, collections.Iterator)) print(next(fib))
fib is Iterable? True fib is Iterator? False Traceback (most recent call last): File "D:/MyProject/Python/insight-tools-rest/test.py", line 27, in <module> print(next(fib)) TypeError: 'Fib' object is not an iterator
迭代器(Iterator)
迭代器是用于進(jìn)行迭代操作的對(duì)象,它可以像列表一樣使用 for 迭代獲取其中的每一個(gè)元素。當(dāng)然,列表、字典屬于可迭代對(duì)象,但并不是迭代器。
要將列表、字典等常見(jiàn)的可迭代對(duì)象變成迭代器,需要使用 iter 或者 __iter__() 進(jìn)行作用:
l = [1, 2, 3] d = {'a': 1, 'b': 2, 'c': 3} print(type(l)) print(type(d)) l = l.__iter__() d = iter(d) print(type(l)) print(type(d))
<class 'list'> <class 'dict'> <class 'list_iterator'> <class 'dict_keyiterator'>
迭代器與列表的區(qū)別在于,列表是一次性把所有的元素加載到內(nèi)存,迭代器則是使用延遲計(jì)算的方式返回元素,只有在調(diào)用 next 方法的時(shí)候才去計(jì)算并返回該元素,也即 call by need 的方式,for 循環(huán)本質(zhì)上也是不斷調(diào)用迭代器的 next 方法來(lái)進(jìn)行遍歷。
如果要將一個(gè)可迭代對(duì)象變成迭代器的話,還需要實(shí)現(xiàn)一個(gè) __next__ 方法:
class Fib: def __init__(self, n): self.prev = 0 self.cur = 1 self.n = n def __iter__(self): return self def __next__(self): if self.n > 0: value = self.cur self.cur += self.prev self.prev = value self.n -= 1 return value else: raise StopIteration() fib = Fib(5) import collections print('fib is Iterable? ', isinstance(fib, collections.Iterable)) print('fib is Iterator? ', isinstance(fib, collections.Iterator)) print([i for i in fib])
fib is Iterable? True
fib is Iterator? True
[1, 1, 2, 3, 5]
生成器(Generator)
普通函數(shù)一般使用 return 返回一個(gè)值,但在 Python 中還有一種函數(shù),用關(guān)鍵字 yield 來(lái)返回值,這種函數(shù)叫生成器。函數(shù)被調(diào)用時(shí)會(huì)返回一個(gè)生成器對(duì)象,生成器本質(zhì)上還是一個(gè)迭代器(特殊的迭代器,實(shí)現(xiàn)方式不一樣),因此在迭代操作中,生成器對(duì)象的行為和迭代器非常相似。下面是使用生成器實(shí)現(xiàn)的斐波那契數(shù)列:
def fib(n): prev = 0 cur = 1 while n > 0: yield cur n -= 1 prev, cur = cur, cur + prev # tmp = prev # prev = cur # cur = cur + tmp print([i for i in fib(5)])
[1, 1, 2, 3, 5]
當(dāng)然也可以使用 next 不斷去遍歷:
fib = fib(5) print(next(fib)) print(next(fib)) print(next(fib)) print(next(fib)) print(next(fib))
1
1
2
3
5
到此這篇關(guān)于Python中的迭代器和生成器詳解的文章就介紹到這了,更多相關(guān)迭代器和生成器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
完美解決torch.cuda.is_available()一直返回False的玄學(xué)方法
這篇文章主要介紹了完美解決torch.cuda.is_available()一直返回False的玄學(xué)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02Pycharm如何設(shè)置默認(rèn)請(qǐng)求頭和切換python環(huán)境
這篇文章主要介紹了Pycharm如何設(shè)置默認(rèn)請(qǐng)求頭和切換python環(huán)境問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06Python手動(dòng)實(shí)現(xiàn)Hough圓變換的示例代碼
Hough圓變換的原理相信大家都非常清楚了,但是手動(dòng)實(shí)現(xiàn)的比較少。這篇文章將為大家介紹手動(dòng)實(shí)現(xiàn)Hough圓變換的示例代碼,需要的可以了解一下2022-01-01django重新生成數(shù)據(jù)庫(kù)中的某張表方法
今天小編就為大家分享一篇django重新生成數(shù)據(jù)庫(kù)中的某張表方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-08-08三個(gè)Python常用的數(shù)據(jù)清洗處理方式總結(jié)
這篇文章主要為大家詳細(xì)介紹了python數(shù)據(jù)處理過(guò)程中三個(gè)主要的數(shù)據(jù)清洗說(shuō)明,分別是缺失值/空格/重復(fù)值的數(shù)據(jù)清洗,感興趣的小伙伴可以了解一下2022-12-12Python django框架應(yīng)用中實(shí)現(xiàn)獲取訪問(wèn)者ip地址示例
這篇文章主要介紹了Python django框架應(yīng)用中實(shí)現(xiàn)獲取訪問(wèn)者ip地址,涉及Python Request模塊相關(guān)函數(shù)使用技巧,需要的朋友可以參考下2019-05-05python中g(shù)etattr函數(shù)使用方法 getattr實(shí)現(xiàn)工廠模式
這篇文章主要介紹了python中g(shù)etattr()這個(gè)函數(shù)的一些用法,大家參考使用吧2014-01-01