迭代:遍歷挨個取元素
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