python之生成器和迭代器

概念解釋

			迭代:遍歷挨個取元素
			a = [1,2,3,4,5,6]
			for i in a:
			    print(i)  #1,2,3,4,5,6
			可迭代對象:實現了迭代器的對象
									在產生這個對象的類中定義了__iter__()方法
			迭代器:迭代器在類中實現了兩個對象
							__iter__()方法      返回迭代器對象本身
							__next__()方法    返回下一個元素
			這裏需要注意:可迭代對象不一定是迭代器,而迭代器一定是可迭代對象

類實現迭代器和可迭代對象

			判斷是否爲可迭代對象:
 				from collections import Iterable
				a = [1,2,3,4,5,6]
				print(isinstance(a,Iterable))    #判斷是否是可迭代對象
			將可迭代對象轉換爲迭代器:
				from collections import Iterable,Iterator
				a = [1,2,3,4,5,6]
				print(isinstance(a,Iterable))    #True
				str_a = iter(a)
				print(isinstance(str_a,Iterator))    #True
			類實現一個可迭代對象:
				class Die_daiqi(object):
				    def __init__(self,diedai):
				        self.diedai = diedai
				    def __iter__(self):
				        return iter(self.diedai.split(' '))
				ret = Die_daiqi('my name is eric')
				for i in ret:
				    print(i)  #注意:這裏不能用next獲取元素,因爲迭代器沒有next方法,請看下面的
			類實現一個一個迭代器:
				class Jiuan(object):
				    def __init__(self,a,b,c=1):
				        self.a = a
				        self.b = b
				        self.c = c
				    def __iter__(self):
				        return self
				    def __next__(self):      #注意和上面區別
				        if self.a <= self.b:
				            num  = self.a
				            self.a+= self.c
				            return num
				        else:
				            raise StopIteration('沒有元素了')    #StopIteration異常
				a = Jiuan(1,10)
				for i in a:
				    print(i)

比較好的迭代器

		counter:無限序列
	 			from itertools import count,islice,cycle
				counter = count(3,2)
				for i in counter:
				    print(i)    #無限序列
		cycle:將一個有限序列變成無限序列
				from itertools import count,islice,cycle
				counter = count(3,2)
				re = islice(counter,0,20)
				print(list(re))
		islice:從無限的迭代器中產生一個有限的序列
				re = [1,2,3,4,5]
				result = cycle(re)
				for i in range(1,9):
				    print(next(result))
	迭代器實現斐波拉契數列:
				class Fblq(object):
				    def __init__(self):
				        self.a = 0
				        self.b = 1
				    def __iter__(self):
				        return self
				    def __next__(self):
				        num = self.a
				        self.a,self.b = self.b,self.a+self.b
				        return num
				ret = Fblq()
				re = islice(ret,1,10)
				print(list(re))

生成器

	兩種實現方式:
					1.定義一個函數用yield關鍵字,用了這個關鍵字這個函數就是生成器對象
					2.生成器表達式(i  for i in rang(10))
	判斷是否是生成器對象;
					from collections import Generator
					a = (i for i in range(10))
					print(isinstance(a,Generator))   #True
	生成器函數:
					def scq():
					    st = 1
					    while True:
					        yield st
					        st+=2
					        print('haha')
					rt = scq()
					print(next(rt))    #注意這裏打印的是1
					print(next(rt))    #注意這裏打印的是haha,3
					print(next(rt))    #注意這裏打印的是haha,5
					這裏給大家解釋一下yield關鍵字:
							當執行到yield st這裏的時候代碼會暫停同時把1給返回回去
							再次執行的時候還是從這裏開始執行,st+=2結果是3下面打印haha
							這時候st+2等於3,執行到yield st把3彈出去,結果就是haha,3
							下面也是同樣,st+=2結果是5,執行到print('haha')把haha打印出來
							執行到yield st把5彈出來,以此類推。
	生成器版本斐波拉契:
					def cv():
					    a = 0
					    b = 1
					    while True:
					        yield b
					        a,b = b,a+b
					ret = cv()
					ct = islice(ret,0,10)  #0到10個項
					print(list(ct))
	send()和close():
		send():給yield關鍵字傳入參數
						def scq():
				    b = 1
				    st = 1
				    while True:
				        a = yield b
				        if isinstance(a,int):
				            st = a
				        b+=st
				        print('haha')
				rt = scq()
				print(next(rt)) #1
				print(next(rt)) #haha 3
				print(rt.send(2))     #haha,4
		close():結束生成器,再用next則報錯
			def scq():
				    b = 1
				    st = 1
				    while True:
				        a = yield b
				        if isinstance(a,int):
				            st = a
				        b+=st
				        print('haha')
				
				rt = scq()
				print(next(rt)) #1
				print(next(rt)) #haha 3
				print(rt.send(2))
				rt.close()
				print(next(rt))    #StopIteration

總結:

		1.共同點:
						都可以使用next獲取元素
		2.不同點:
						生成器有send和close方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章