Python 迭代器與生成器實例詳解
一、如何實現可迭代對象和迭代器對象
1.由可迭代對象得到迭代器對象
例如l就是可迭代對象,iter(l)是迭代器對象
In [1]: l = [1,2,3,4]In [2]: l.__iter__Out[2]: <method-wrapper '__iter__' of list object at 0x000000000426C7C8>In [3]: t = iter(l)In [4]: t.next()Out[4]: 1In [5]: t.next()Out[5]: 2In [6]: t.next()Out[6]: 3In [7]: t.next()Out[7]: 4In [8]: t.next()---------------------------------------------------------------------------StopIteration Traceback (most recent call last)<ipython-input-8-3660e2a3d509> in <module>()----> 1 t.next()StopIteration:for x in l: print xfor 循環的工作流程,就是先有iter(l)得到一個t,然后不停的調用t.nex(),到最后捕獲到StopIteration,就結束迭代
# 下面這種直接調用函數的方法如果數據量大的時候會對網絡IO要求比較高,可以采用迭代器的方法
def getWeather(city): r = requests.get(u'http://wthrcdn.etouch.cn/weather_mini?city='+city) data = r.json()['data']['forecast'][0] return '%s:%s,%s' %(city, data['low'], data['high'])print getWeather(u'北京')返回值:
北京:低溫 13℃,高溫 28℃
實現一個迭代器對象WeatherIterator,next 方法每次返回一個城市氣溫
實現一個可迭代對象WeatherIterable,iter方法返回一個迭代器對象
# -*- coding:utf-8 -*-import requestsfrom collections import Iterable, Iteratorclass WeatherIterator(Iterator): def __init__(self, cities): self.cities = cities self.index = 0 def getWeather(self,city): r = requests.get(u'http://wthrcdn.etouch.cn/weather_mini?city='+city) data = r.json()['data']['forecast'][0] return '%s:%s,%s' %(city, data['low'], data['high']) def next(self): if self.index == len(self.cities): raise StopIteration city = self.cities[self.index] self.index += 1 return self.getWeather(city)class WeatherIterable(Iterable): def __init__(self, cities): self.cities = cities def __iter__(self): return WeatherIterator(self.cities)for x in WeatherIterable([u'北京',u'上海',u'廣州',u'深圳']): print x.encode('utf-8')輸出:北京:低溫 13℃,高溫 28℃上海:低溫 14℃,高溫 22℃廣州:低溫 17℃,高溫 23℃深圳:低溫 18℃,高溫 24℃二、使用生成器函數實現可迭代對象
1.實現一個可迭代對象的類,它能迭代出給定范圍內所有素數
素數定義為在大于1的自然數中,除了1和它本身以外不再有其他因數的數稱為素數。
一個帶有 yield 的函數就是一個 generator,它和普通函數不同,生成一個 generator 看起來像函數調用,但不會執行任何函數代碼,直到對其調用 next()(在 for 循環中會自動調用 next())才開始執行。雖然執行流程仍按函數的流程執行,但每執行到一個 yield 語句就會中斷,并返回一個迭代值,下次執行時從 yield 的下一個語句繼續執行。看起來就好像一個函數在正常執行的過程中被 yield 中斷了數次,每次中斷都會通過 yield 返回當前的迭代值。
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 xrange(2, k): if k % i == 0: return False return True def __iter__(self): for k in xrange(self.start, self.end + 1): if self.isPrimeNum(k): yield kfor x in PrimeNumbers(1, 10): print x輸出:2357
三、實現反向迭代
1.反向進行迭代
例如: 實現一個浮點數發生器FloatRange(和xrange類似),根據給定范圍(start, end)和步徑值(step)產生一系列連續浮點數,如迭代FloatRange(3.0,4.0,0.2)可產生序列:
正向: 3.0 -> 3.2 -> 3.4 -> 3.6 -> 3.8 -> 4.0
反向: 4.0 -> 3.8 -> 3.6 -> 3.4 -> 3.2 -> 3.0
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 round(t,14) <= round(self.end, 14): yield t t = t + self.step def __reversed__(self): t = self.end while round(t, 14) >= round(self.start, 14): yield t t = t - self.stepfor x in reversed(FloatRange(3.0, 4.0, 0.2)): print x輸出:4.03.83.63.43.23.0for x in FloatRange(3.0, 4.0, 0.2):
print x
輸出:
3.0
3.2
3.4
3.6
3.8
4.0
上面代碼采用round函數是因為浮點數比較會有精度問題,所以需要進行四舍五入
2.對迭代器進行切片操作
例如: 有某個文本文件,想讀取其中某范圍的內容,如100-300行之間的內容,python中文本文件是可迭代對象,是否可以使用類似列表切片的方式得到一個100-300行文件內容的生成器
使用標準庫中的itertools.islice,它能返回一個迭代對象切片的生成器
f = open('/var/log/dmesg')from itertools import islice# 對文件內容100到300行之間進行切片,返回的是個生成器對象,默認
主站蜘蛛池模板:
静宁县|
长宁县|
吴堡县|
玛沁县|
南京市|
蕲春县|
天气|
建阳市|
灵川县|
濉溪县|
山阴县|
克拉玛依市|
海林市|
安福县|
长沙县|
读书|
同德县|
江油市|
南雄市|
怀安县|
元谋县|
洛浦县|
拉萨市|
凤冈县|
青浦区|
霍邱县|
武冈市|
柘城县|
固原市|
浦城县|
应用必备|
象山县|
德钦县|
临澧县|
乌拉特前旗|
乌拉特中旗|
固镇县|
阳原县|
灵宝市|
博白县|
呼和浩特市|