相關免費學習推薦:python教學(影片)
迭代器模式是一種經典的軟體設計模式,現在許多程式語言都內建了這種設計模式。在Python的原始資料類型中,可以進行for迴圈的都屬於可迭代的類型。當然,也可以使用iter函數取得到對應的迭代器,然後遍歷該物件。如下面的程式碼:
l = [1, 3] # 可迭代对象 __iter__t = iter(l) #获取迭代器对象print(t.__next__()) print(t.__next__())# print(t.__next__()) # 报异常复制代码
要實作一個可迭代對象,一般先要實作對應的迭代器對象。在Python實作迭代器,其實只需要實作__next__方法。但collections套件中的Iterator類別將__next__方法定義為了抽象方法,筆者認為鑑於程式的可讀性,在實作迭代器時不妨繼承Iterator類別。
from random import samplefrom collections import Iterable, Iteratorclass WeatherIterator(Iterator): def __init__(self, cities): self.cities = cities self.index = 0 def getWeather(self, city): return (city, sample(['sun','wind','yu'], 1)[0]) def __next__(self): if self.index == len(self.cities): raise StopIteration city = self.cities[self.index] self.index += 1 return self.getWeather(city)复制代码
實作可迭代的對象,也只要實作__iter__方法即可,同樣的,collections套件中的Iterable類別也將__iter__方法定義為抽象類別。
from collections import Iterableclass WeatherIterable(Iterable): def __init__(self, cities): self.cities = cities self.index = 0 def __iter__(self): return WeatherIterator(self.cities)复制代码
這樣就可以使用for迴圈來迭代了。
for weather in WeatherIterable(['北京', '上海', '广州']): print(weather)复制代码
先看如下程式碼:
def gen(): print("step 1") yield 1 print("step 2") yield 2 print("step 3") yield 3复制代码
上面的gen函數的回傳值就是一個生成器物件。
g = gen() g.__next__() print(g.__next__()) print(g.__next__())复制代码
如上述程式碼,每呼叫一次生成器的__next__方法,它都會執行一段gen函數,遇到yield關鍵字為止,並傳回其後的東西。因此,生成器可以理解為一種能夠被打斷的函數。
注意:生成器物件也是可迭代的物件。
for x in g: print(x)复制代码
將__iter__方法實作為生成器函數,就可以實作可迭代物件。
class PrimeNumbers: def __init__(self, start, end): self.start = start self.end = end def isPrimeNum(self, k): #判断是否是素数 if k < 2: return False for i in range(2, k): if k % i == 0: return False return True def __iter__(self): for k in range(self.start, self.end + 1): if self.isPrimeNum(k): yield kfor num in PrimeNumbers(2, 100): print(num)复制代码
iter函數可以取得可迭代物件的正向迭代器,reversed函數則可以取得可迭代物件的反向迭代器。
l = [1, 2, 3, 4, 5]for x in reversed(l): print(x)复制代码
要實作反向迭代,實作__reversed__方法即可。
class FloatRange: def __init__(self, start, end, step=0.1): self.start = start self.end = end self.step = step def __iter__(self): t = self.start while t <= self.end: yield t t += self.step def __reversed__(self): t = self.end while t >= self.start: yield t t -= self.stepfor x in FloatRange(1.0, 4.0, 0.5): print(x)for x in reversed(FloatRange(1.0, 4.0, 0.5)): print(x)复制代码
itertools套件中的islice函數,可以可迭代物件進行切片操作。
from itertools import islicefor x in islice(FloatRange(1.0, 4.0, 0.5), 2, 5): print(x)复制代码
使用zip方法,將對應元素組成一個元組。
for w, e, m in zip([1, 2, 3, 4], ('a', 'b', 'c','d'), [5, 6, 7, 8]): print(w, e, m)复制代码
使用itertools套件中的chain函數,將多個可迭代物件串聯起來。 使用zip方法,將對應元素組成一個元組。
from itertools import chainfor x in chain([1, 2, 3, 4], ('a', 'b', 'c','d')): print(x)复制代码
以上是寫給Python程式設計高手2:迭代器的詳細內容。更多資訊請關注PHP中文網其他相關文章!