支持next和__iter__方法的類,
其中next需要拋出StopIteration異常或返回迭代值,
__iter__需要返回迭代器自己,
也可以實現send函數,但要保證send函數調用next。
class MyIterator(object): def __init__(self, step): self.step = step def next(self): """Returns the next element.""" if self.step == 0: raise StopIteration # 不拋出這個異常,for循環就不能捕獲而已,那么for循環不能停止 self.step -= 1 # 沒有return 就返回None return self.step def send(self,data): return self.next() def __iter__(self): return self # Returns the iterator itselffor el in MyIterator(4): PRint el2,xrange:
xrange比迭代器高一個檔次。a = xrange(5)返回一個xrange實例對象。xrange實例對象只支持__iter__方法,不支持next。
xrange實例對象的__iter__方法返回一個迭代器。
所以迭代器是一次性用品,而xrange可以一直返回初始狀態一樣的迭代器,可以重復使用。
for循環,首先調用對象的__iter__方法得到迭代器,然后調用迭代器的next方法。
a = xrange(5) # xrange實例對象b = a.__iter__() # 迭代器對象c = a.__iter__() # 迭代器對象,xrange實例對象可以多次返回相同初始狀態的迭代器print list(b)print list(b) # 為空,迭代器只能用一次print a[2],a[0] # xrange實例對象還支持切片來索引數據print list(a)print list(a) # 多次使用3,yield和生成器:
yield:使用協程進行用戶態上下文切換的技術。
生成器:使用yield技術,返回支持迭代器的next、__iter__和send接口的對象。
生成器是一直執行代碼,直到遇到yeild,就返回結果值和接受輸入值,
可以有多個yeild,不一定非得是循環,
只要沒有yeild可以執行時,就拋出stopiterantion。
for只不過是有處理stopiterantion異常的代碼而已。
a.next()和a.send(None) 作用是一樣的,但第一次調用生成器時,請一定使用next()語句或是send(None)。
4,簡單的例子:
from collections import Iterableisinstance('abc', Iterable) # str是否可迭代isinstance(123, Iterable) # 整數是否可迭代L = [x * x for x in range(10)] # 列表解析式print Lg = (x * x for x in range(10)) # 返回一個生成器print gdef fib(max): '斐波拉契數列用列表生成式寫不出來,但是,用函數把它打印出來卻很容易' n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1for i in fib(20): print ifrom itertools import groupbydef compress(data): return ( (len(list(group)), name) for name, group in groupby(data) ) # 返回一個生成器def decompress(data): return (car * size for size, car in data) # 返回一個生成器list(compress('get uuuuuuuuuuuuuuuuuup'))compressed = compress('get uuuuuuuuuuuuuuuuuup')''.join(decompress(compressed))5,兩種方法實現計數器:閉包和生成器:
import numpy as npimport pandas as pdkey_small = ['one','two','one','two','one']df_small = pd.DataFrame(np.random.randn(5,3),index=['joe','steve','wes','jim','travis'],columns=['a','b','c'])gb_small = df_small.groupby(key_small)def f_wrapper(): '閉包計數器' count = [0] def f(obj): count[0] += 1 print '/nSTART',count[0],'/n',obj,'/nEND',count[0],'/n' return ff = f_wrapper()gb_small.agg(f)print '-----------------------------------------------------------'def f_counter(): '生成器計數器' count = 0 while True: a = yield count count += 1 if count > 100: breakcounter = f_counter() # '記住:當函數被調用時,他們返回一個生成器對象,這個對象支持迭代器接口。一定要調用,才能生成' def f(obj): count = counter.next() print '/nSTART',count,'/n',obj,'/nEND',count,'/n' gb_small.agg(f)(如果有什么說的不對的地方,歡迎大家多多批評指正。)
新聞熱點
疑難解答