Python 迭代器与生成器实例详解
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]: 1 In [5]: t.next() Out[5]: 2 In [6]: t.next() Out[6]: 3 In [7]: t.next() Out[7]: 4 In [8]: t.next() --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-8-3660e2a3d509> in <module>() ----> 1 t.next() StopIteration: for x in l: print x for 循环的工作流程,就是先有iter(l)得到一个t,然后不停的调用t.nex(),到最后捕获到StopIteration,就结束迭代
# 下面这种直接调用函数的方法如果数据量大的时候会对网络IO要求比较高,可以采用迭代器的方法
def getWeather(city): r = requests.get(u'http://wthrcdn.etouch.cn/weather_mini"htmlcode"># -*- coding:utf-8 -*- import requests from collections import Iterable, Iterator class 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"htmlcode">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 k for x in PrimeNumbers(1, 10): print x 输出: 2 3 5 7三、实现反向迭代
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.step for x in reversed(FloatRange(3.0, 4.0, 0.2)): print x 输出: 4.0 3.8 3.6 3.4 3.2 3.0 for 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行之间进行切片,返回的是个生成器对象,默认歩径是1 islice(f, 100, 300) # 前500行内容 islice(f, 500) # 100行到末尾结束内容 islice(f, 100, None) ps: 每次使用islice要重新申请对象,它会消耗原来的迭代对象四、 迭代多个对象
1.在一个for语句中迭代多个可迭代对象
1、某班学生考试成绩语文、数学、英语分别存储在3个列表中,同时迭代三个列表,计算三个学生的总分(并行)
2、某年级四个班,某次考试每班英语成绩分别存储在4个列表中,依次迭代每个列表,统计全学年英语成绩高于90分人数(串行)
解决方案:
并行: 使用内置函数zip,它能将多个可迭代对象合并,每次迭代返回一个元组
from random import randint chinese = [randint(60,100) for _ in xrange(40)] math = [randint(60,100) for _ in xrange(40)] english = [randint(60,100) for _ in xrange(40)] total = [] for c,m,e in zip(chinese, math,english): total.append(c+m+e) print total 输出: [204, 227, 238, 201, 227, 205, 251, 274, 210, 242, 220, 239, 237, 207, 230, 267, 263, 240, 247, 249, 255, 268, 209, 270, 259, 251, 245, 262, 234, 221, 236, 250, 251, 249, 242, 255, 232, 272, 237, 253]串行: 使用标准库中的itertools.chain,它能将多个可迭代对象连接
from random import randint from itertools import chain class1 = [randint(60,100) for _ in xrange(40)] class2 = [randint(60,100) for _ in xrange(42)] class3 = [randint(60,100) for _ in xrange(39)] class4 = [randint(60,100) for _ in xrange(43)] count = 0 for s in chain(class1, class2, class3, class4): if s > 90: count = count + 1 print count 输出: 38感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
下一篇:Python字符串处理实例详解