python生成器
2016-02-22 15:25
429 查看
迭代器是一个对象,而生成器是一个函数,迭代器和生成器是python中两个非常强大的特性,编写程序时你可以不使用生成器达到同样的效果,但是生成器让你的程序更加pythonic。创建生成器非常简单,只要在函数中加入yield语句即可。函数中每次使用yield产生一个值,函数就返回该值,然后停止执行,等待被激活,被激活后继续在原来的位置执行。下边的例子实现了同样的功能:
不过, 迭代器也有一些限制. 例如你不能向后移动, 不能回到开始, 也不能复制一个迭代器.如果你要再次(或者是同时)迭代同个对象, 你只能去创建另一个迭代器对象. 不过, 这并不糟糕,因为还有其他的工具来帮助你使用迭代器.
reversed() 内建函数将返回一个反序访问的迭代器. enumerate() 内建函数同样也返回迭代器.另外两个新的内建函数, any() 和 all() , 在 Python 2.5 中新增, 如果迭代器中某个/所有条目的值都为布尔真时,则它们返回值为真. 本章先前部分我们展示了如何在 for 循环中通过索引或是可迭代对象来遍历条目. 同时 Python 还提供了一整个 itertools 模块, 它包含各种有用的迭代器.
迭代器工作原理
如果这是一个实际应用程序, 那么我们需要把代码放在一个 try-except 块中. 序列现在会自
动地产生它们自己的迭代器, 所以一个 for 循环:
实际上是这样工作的:
另外, Python 还引进了三个新的内建字典方法来定义迭代: myDict.iterkeys() (通过 keys 迭
代), myDict.itervalues() (通过 values 迭代), 以及 myDicit.iteritems() (通过 key/value 对来迭代). 注意, in 操作符也可以用于检查字典的 key 是否存在 , 之前的布尔表达式myDict.has_key(anyKey) 可以被简写为 anyKey in myDict .
===文件===
文件对象生成的迭代器会自动调用 readline() 方法. 这样, 循环就可以访问文本文件的所有
行. 程序员可以使用 更简单的 for eachLine in myFile 替换 for eachLine in myFile.readlines() :
一个流行的例子就是循环列表的时候删除满足(或不满足)特定条件的项:
除列表外的其他序列都是不可变的, 所以危险就发生在这里. 一个序列的迭代器只是记录你当前到达第多少个元素, 所以如果你在迭代时改变了元素, 更新会立即反映到你所迭代的条目上.在迭代字典的 key 时, 你绝对不能改变这个字典. 使用字典的 keys() 方法是可以的, 因为keys() 返回一个独立于字典的列表. 而迭代器是与实际对象绑定在一起的, 它将不会继续执行下去:
这样可以避免有缺陷的代码. 更多有关迭代器的细节请参阅 PEP 234 .
如果你传递一个参数给 iter() , 它会检查你传递的是不是一个序列, 如果是, 那么很简单:
根据索引从 0 一直迭代到序列结束. 另一个创建迭代器的方法是使用类, 我们将在第 13 章详细
介绍, 一个实现了 __iter__() 和 next() 方法的类可以作为迭代器使用.
如果是传递两个参数给 iter() , 它会重复地调用 func , 直到迭代器的下个值等于sentinel .
#!/usr/bin/env python #coding=utf-8 def fib(): a,b = 0,1 while 1: a,b = b,a+b yield a for f in fib(): if f < 10000: print (f) else: break 1 1 2 3 5 8 13 21 34 55 89
如何迭代?
根本上说, 迭代器就是有一个 next() 方法的对象, 而不是通过索引来计数. 当你或是一个循环机制(例如 for 语句)需要下一个项时, 调用迭代器的 next() 方法就可以获得它. 条目全部取出后, 会引发一个 StopIteration 异常, 这并不表示错误发生, 只是告诉外部调用者, 迭代完成.不过, 迭代器也有一些限制. 例如你不能向后移动, 不能回到开始, 也不能复制一个迭代器.如果你要再次(或者是同时)迭代同个对象, 你只能去创建另一个迭代器对象. 不过, 这并不糟糕,因为还有其他的工具来帮助你使用迭代器.
reversed() 内建函数将返回一个反序访问的迭代器. enumerate() 内建函数同样也返回迭代器.另外两个新的内建函数, any() 和 all() , 在 Python 2.5 中新增, 如果迭代器中某个/所有条目的值都为布尔真时,则它们返回值为真. 本章先前部分我们展示了如何在 for 循环中通过索引或是可迭代对象来遍历条目. 同时 Python 还提供了一整个 itertools 模块, 它包含各种有用的迭代器.
迭代器工作原理
如果这是一个实际应用程序, 那么我们需要把代码放在一个 try-except 块中. 序列现在会自
动地产生它们自己的迭代器, 所以一个 for 循环:
for i in seq: do_something_to(i)
实际上是这样工作的:
fetch = seq.__iter__ #iter(seq) while True: try: i = fetch.next() except StopIteration: break do_something_to(i)
另外, Python 还引进了三个新的内建字典方法来定义迭代: myDict.iterkeys() (通过 keys 迭
代), myDict.itervalues() (通过 values 迭代), 以及 myDicit.iteritems() (通过 key/value 对来迭代). 注意, in 操作符也可以用于检查字典的 key 是否存在 , 之前的布尔表达式myDict.has_key(anyKey) 可以被简写为 anyKey in myDict .
===文件===
文件对象生成的迭代器会自动调用 readline() 方法. 这样, 循环就可以访问文本文件的所有
行. 程序员可以使用 更简单的 for eachLine in myFile 替换 for eachLine in myFile.readlines() :
>>>myFile=open(‘config-win.txt’) >>> for eachLine in myFile: … print eachLine, # comma suppresses extra n … [EditorWindow] font-name: courier new font-size: 10 >>> myFile.close()
可变对象和迭代器
记住,在迭代可变对象的时候修改它们并不是个好主意. 这在迭代器出现之前就是一个问题.一个流行的例子就是循环列表的时候删除满足(或不满足)特定条件的项:
for eachURL in allURLs: if not eachURL.startswith(‘http://’): allURLs.remove(eachURL) # YIKES!!
除列表外的其他序列都是不可变的, 所以危险就发生在这里. 一个序列的迭代器只是记录你当前到达第多少个元素, 所以如果你在迭代时改变了元素, 更新会立即反映到你所迭代的条目上.在迭代字典的 key 时, 你绝对不能改变这个字典. 使用字典的 keys() 方法是可以的, 因为keys() 返回一个独立于字典的列表. 而迭代器是与实际对象绑定在一起的, 它将不会继续执行下去:
myDict = {'a': 1, 'b': 2, 'b': 3, 'd': 4} for eachKey in myDict: print (eachKey, myDict[eachKey]) del myDict[eachKey] ''' 结果: d 4 Traceback (most recent call last): File "test.py", line 2, in <module> for eachKey in myDict: RuntimeError: dictionary changed size during iteration '''
这样可以避免有缺陷的代码. 更多有关迭代器的细节请参阅 PEP 234 .
如何创建迭代器
对一个对象调用 iter() 就可以得到它的迭代器. 它的语法如下:iter(obj) iter(func, sentinel)
如果你传递一个参数给 iter() , 它会检查你传递的是不是一个序列, 如果是, 那么很简单:
根据索引从 0 一直迭代到序列结束. 另一个创建迭代器的方法是使用类, 我们将在第 13 章详细
介绍, 一个实现了 __iter__() 和 next() 方法的类可以作为迭代器使用.
如果是传递两个参数给 iter() , 它会重复地调用 func , 直到迭代器的下个值等于sentinel .
相关文章推荐
- python一键打包
- python学习笔记
- 【Python】python读取文件操作mysql
- python string unicode字符串
- python:使用paramiko批量管理服务器(含密钥和密码)
- 【python】编程语言入门经典100例--8
- python 文件、目录操作(新增、移动、删除等)
- 【python】编程语言入门经典100例--7
- 【python】编程语言入门经典100例--6
- python【番外篇】:将xml中的数据写入到mysql中
- python解析xml文件
- Python 迭代器 & __iter__方法
- #!/usr/bin/env python与#!/usr/bin/python的区别
- python第六天
- python开发之list操作实例分析
- 不务正业--用python爬虫抓取Konachan的图片并保存到本地文件
- Python split() 函数 拆分字符串 将字符串转化为列
- [Python学习]Python中的with语法
- python实战系列之MySQL主从状态监控(09)
- ]python time, datetime, string, timestamp相互转换