1. 程式人生 > >(23)叠代器、生成器

(23)叠代器、生成器

ati ever __next__ 使用 生成 return 導致 += for loop

*可叠代對象
list,tuple,dict,str,generator(生成器)

*叠代器
叠代器肯定是iterable類型的對象,它是包含有next(Python 2) 方法或者__next__(Python 3) 方法和__iter__(返回self)方法的一個特殊對象,可以對這樣一個對象進行for loop循環訪問。
對於實現next方法需要註意的是,當沒有下一個元素的時候必須拋出StopIteration異常。
當遍歷一個叠代器的時候,它會修改內部狀態,導致你只能向前獲取下一個元素,不能通過叠代器訪問後面一個元素;也就是說當你通過叠代器訪問了一個元素以後,在當前循環中不能後退繼續訪問該元素了,除非你重新生產叠代器對象進行遍歷。
另外需要註意的是在叠代器中next方法是return下一個元素的值,不像下面介紹的生成器yield一個元素。

class Iterator_:
def __init__(self, s, e):
self.current = s
self.end = e
def __iter__(self):
return self
def next(self):
if self.current < self.end:
self.index = self.current
self.current += 1
return self.index
else:
raise StopIteration
it = Iterator_(5, 8)
for i in it:
print "iterator:" + str(i)
#never print
for i in it:
print "second iterator:" + str(i)
#print again
it = Iterator_(5, 8)
for i in it:
print "second iterator:" + str(i)
#輸出
iterator:5
iterator:6
iterator:7
second iterator:5
second iterator:6
second iterator:7

* 生成器
對於一個生成器它一定是一個叠代器,可以通過for loop進行訪問其中的元素,但是一個叠代器卻很明顯的不一定是生成器。
定義叠代器有兩種方式,第一個是使用yield關鍵詞,另外一個是生成器表達式"()"。
對於一個方法在方法體裏加上yield關鍵詞就變成了生成器。yield作用就是返回一個生成器,它會保存當前函數狀態,
記錄下一次函數被調用next的時候運行狀態。當函數沒有下一次運行狀態的時候,再繼續調用next方法,這個時候StopIteration異常就被拋出。
print "generator"
#first way
my_generator = (x for x in range(3))
for i in my_generator:
print i
#second way
def Generator_(l):
n = 0
size = len(l)
while n < size:
yield l[n]
n += 1

ge = Generator_([1, 2, 3])
for g in ge:
print "generator:" + str(g)

(23)叠代器、生成器