Python学习之路六---迭代器、生成器
2015-11-09 15:23
639 查看
迭代器
在Python中,for循环可以用于Python中的任何类型,包括列表、元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引发StopIteration。任何这类的对象在Python中都可以用for循环或其他遍历工具迭代,迭代工具内部会在每次迭代时调用next方法,并且捕捉StopIteration异常来确定何时离开。
使用迭代器一个显而易见的好处就是:每次只从对象中读取一条数据,不会造成内存的过大开销。
比如要逐行读取一个文件的内容,利用readlines()方法,我们可以这么写:
for line in open("a.txt").readlines(): print line
上面的读取文件是把文件一次性加载到内存中,然后打印。当文件很大时这个方法的内存开销就很大了。
利用file的迭代器则可以:
for line in open("a.txt") print line
这种实现不仅运行速度快,而且没有显示的读取文件,知识利用且带起每次读取下一行。
迭代器不要求你事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代至某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件,或是斐波那契数列等等。这个特点被称为延迟计算或惰性求值(Lazy evaluation)。
迭代器更大的功劳是提供了一个统一的访问集合的接口。只要是实现了_iter_()方法的对象,就可以使用迭代器进行访问。
迭代器的两个基本优点:
next方法:返回迭代器的下一个元素
iter方法:返回迭代器对象本身
生成菲波那切数列示例:
代码1
def fab(max): n, a, b = 0, 0, 1 while n < max: print b a, b = b, a + b n = n + 1
代码2
class Fab(object): def __init__(self, max): self.max = max self.n, self.a, self.b = 0, 0, 1 def __iter__(self): return self def next(self): if self.n < self.max: r = self.b self.a, self.b = self.b, self.a + self.b self.n = self.n + 1 return r raise StopIteration()
使用迭代器
可以通过使用内建的工厂函数iter()来获取迭代器对象:eg:
lst = range(2) it = iter(lst) it.next()
生成器
生成器也是属于迭代器,只不过是生成器的函数中一般包含yield语句。当函数调用时,返回一个生成器的对象,这个对象支持迭代器接口。yield就相当于普通函数中的return语句,当做隐形返回对待就可以了。生成器是逐渐产生结果的复杂递归算法的理想实现工具。
八皇后问题
对于八皇后问题,是一个经典的回溯问题,则利用生成器则可以方便的解决。如下:conflict(state,nextx)函数,用来判断函数的在某一位置是否为可用位置。
其中:state代表已排好位置的皇后的元组,则state[i]代表第i行即第i个皇后位于第几列(即位置)(i,state(i))–>>第i行的第state(i)列,nextx代表这个待排皇后的水平位置。
def conflict(state,nextx): #检查是否冲突 nexty = len(state) for i in range(nexty): if abs(state[i]-nextx) in (0,nexty-i): #检查是否位置与以前的皇后位于同一列或者对角线 return True return False def queens(num,state=()): for pos in range(num): if not conflict(state,pos): if pos == num -1: #如果是最后一个皇后则返回方法元组 yield (pos,) else: #如果不是最后一个则将这个位置加入结果元组中 for result in queens(num,state+(pos,)) yield result+(pos,)
相关文章推荐
- Python SocketServer.py
- 【详解】Python统一解密再改进版逻辑分析
- 《用Python玩转数据》第1周学习笔记(Part2)
- 尝试使用Python多线程抓取代理服务器IP地址的示例
- 关于selenium 用Webdrive打开Firefox不含有插件的问题(python)
- 使用Python实现BT种子和磁力链接的相互转换
- Python中MySQLdb和torndb模块对MySQL的断连问题处理
- python 文件操作
- python数据挖掘常用包
- Python之路【第三篇】:Python基础(二)
- 利用doxygen生成python文档
- 使用Python对IP进行转换的一些操作技巧小结
- 64位win&python2.7下gensim环境搭建
- python 多个相同字符串
- python中添加日志记录到文件
- Python第三方库代码总结
- python调用shell
- python实现目录树
- 2015/11/9用Python写游戏,pygame入门(8):按钮和游戏结束
- python培训Day3 随笔