python迭代器与iter()函数实例教程

python迭代器与iter()函数实例教程

发布时间:2014-07-16编辑:
脚本学堂

本文介绍了python迭代器与iter()函数的用法,Python 的迭代无缝地支持序列对象,而且它还允许程序员迭代非序列类型,包括用户定义的对象。  

迭代器是在版本 2.2 被加入 Python 的,它为类序列对象提供了一个类序列的接口。
序列是一组数据结构,你可以利用它们的索引从0 开始一直“迭代“ 到序列的最后一个条目。
用“计数“的方法迭代序列是很简单的。
Python 的迭代无缝地支持序列对象,而且它还允许程序员迭代非序列类型,包括用户定义的对象。

迭代器用起来很灵巧,可以迭代不是序列但表现出序列行为的对象,例如字典的 key,一个文件的行等。
当使用循环迭代一个对象条目时,几乎不可能分辨出它是迭代器还是序列。不必去关注这些,因为 Python 让它象一个序列那样操作。

如何迭代?

迭代器就是有一个 next() 方法的对象,而不是通过索引来计数。当你或是一个循环机制(例如 for 语句)需要下一个项时,调用迭代器的 next() 方法就可以获得它。条目全部取出后,会引发一个 StopIteration 异常,这并不表示错误发生,只是告诉外部调用者,迭代完成.

不过,迭代器也有一些限制。例如你不能向后移动,不能回到开始,也不能复制一个迭代器.如果你要再次(或者是同时)迭代同个对象,你只能去创建另一个迭代器对象。不过,这并不糟糕,因为还有其他的工具来帮助你使用迭代器。(www.jbxue.com 脚本学堂 整理)

reversed() 内建函数将返回一个反序访问的迭代器。enumerate() 内建函数同样也返回迭代器.另外两个新的内建函数,any() 和 all() ,在 Python 2.5 中新增,如果迭代器中某个/所有条目的值都为布尔真时,则它们返回值为真。本章先前部分展示了如何在 for 循环中通过索引或是可迭代对象来遍历条目。同时 Python 还提供了一整个 itertools 模块,它包含各种有用的迭代器.

一,使用迭代器

===序列===

正如先前提到的,迭代 Python 的序列对象和你想像的一样:
 

复制代码代码示例: >>> myTuple = (123,‘xyz’,45.67)

>>> i = iter(myTuple)

>>> i.next()

123

>>> i.next()

‘xyz’

>>> i.next()

45.67

>>> i.next()

Traceback (most recent call last):

File “<stdin>”,line 1,in <module>

StopIteration

 

如果这是一个实际应用程序,那么需要把代码放在一个 try-except 块中。序列现在会自动地产生它们自己的迭代器,所以一个 for 循环: 
 

复制代码代码示例: for i in seq:

    do_something_to(i)

实际工作方式:
 

复制代码代码示例: fetch = iter(seq)

while True:

try:

i = fetch.next()

except StopIteration:

break

do_something_to(i)

 

不过不需要改动你的代码,因为 for 循环会自动调用迭代器的 next() 方法(以及监视StopIteration 异常)。

===字典===

字典和文件是另外两个可迭代的 Python 数据类型。字典的迭代器会遍历它的键(keys).
语句 for eachKey in myDict.keys() 可以缩写为 for eachKey in myDict ,例如:
 

复制代码代码示例: >>> legends = { (‘Poe’,‘author’): (1809,1849,1976),

… (‘Gaudi’,‘architect’): (1852,1906,1987),

… (‘Freud’,‘psychoanalyst’): (1856,1939,1990)

… }

>>> for eachLegend in legends:

… print ‘Name: %stOccupation: %s‘ % eachLegend

… print ‘ Birth: %stDeath: %stAlbum: %sn‘

… % legends[eachLegend]

Name: Freud Occupation: psychoanalyst

Birth: 1856 Death: 1939 Album: 1990

Name: Poe Occupation: author

Birth: 1809 Death: 1849 Album: 1976

Name: Gaudi Occupation: architect

Birth: 1852 Death: 1906 Album: 1987

另外,Python 还引进了三个新的内建字典方法来定义迭代:
myDict.iterkeys() (通过 keys 迭代),myDict.itervalues() (通过 values 迭代),以及 myDicit.iteritems() (通过 key/value 对来迭代)。(www.jbxue.com 脚本学堂 整理)

注意,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,‘c’: 3,‘d’: 4}

>>> for eachKey in myDict:

… print eachKey,myDict[eachKey]

… del myDict[eachKey]

… a 1

Traceback (most recent call last):

File “<stdin>”,line 1,in <module>

RuntimeError: dictionary changed size during iteration

 

这样可以避免有缺陷的代码。更多有关迭代器的细节请参阅 PEP 234 .

三,如何创建迭代器

对一个对象调用 iter() 就可以得到它的迭代器。它的语法如下:
iter(obj)
iter(func,sentinel)
如果传递一个参数给 iter() ,它会检查你传递的是不是一个序列,如果是,那么很简单: 
根据索引从 0 一直迭代到序列结束。另一个创建迭代器的方法是使用类,将在第 13 章详细介绍,一个实现了 __iter__() 和 next() 方法的类可以作为迭代器使用.
如果是传递两个参数给 iter() ,它会重复地调用 func ,直到迭代器的下个值等于sentinel。

您可能感兴趣的文章:

   
上一篇:
python中enumerate函数遍历元素实例教程

下一篇:
python版加密解密函数authcode的例子

与 python迭代器与iter()函数实例教程 有关的文章

 

    原文作者:mofy
    原文地址: https://www.cnblogs.com/z-books/p/5316947.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞