Python基础:07迭代器

来源:互联网 发布:万网域名修改dns 编辑:程序博客网 时间:2024/05/05 09:53

        迭代器是在版本 2.2 被加入Python 的,它为类序列对象提供了一个类序列的接口。Python 的迭代无缝地支持序列对象,而且它还允许迭代非序列类型,包括用户定义的对象。它的出现,对列表迭代、字典迭代带来了性能上的增强。

        迭代器用起来很灵巧,可以迭代不是序列但表现出序列行为的对象,例如字典的 key ,一个文件的行,等等。当你使用循环迭代一个对象条目时,你几乎不可能分辨出它是迭代器还是序列。

 

        根本上说,迭代器就是一个实现了 next() 方法的对象,当你需要下一个项时(或在一个像for语句这样的循环机制中),调用迭代器的 next() 方法就可以获得它。条目全部取出后,会引发一个 StopIteration异常,这并不表示错误发生,只是告诉外部调用者,迭代完成。

        不过,迭代器也有一些限制。例如你不能向后移动,不能回到开始,也不能复制一个迭代器。如果要再次(或者是同时)迭代同个对象,你只能去创建另一个迭代器对象。

 

        简单实用迭代器的例子如下:

>>> 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 "", line 1, in ?

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 。

        另外,Python 还引进了三个新的内建字典方法来定义迭代:

myDict.iterkeys() (通过 keys 迭代),

myDict.itervalues() (通过 values 迭代),

myDicit.iteritems() (通过 key/value 对来迭代)。

 

        文件对象生成的迭代器会自动调用 readline() 方法。这样,循环就可以访问文本文件的所有行。可以使用更简单的for eachLine in myFile 替换 for eachLine in myFile.readlines()。

 

        记住,在迭代可变对象的时候修改它们不是个好主意,比如在迭代字典的 key 时,你绝对不能改变这个字典。

>>> 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 "",line 1,in ?

RuntimeError:dictionary changed size during iteration

        使用字典的keys() 方法是可以的,因为keys()返回一个独立于字典的列表:

>>> for eachKey in myDict.keys():

...    print  eachKey, myDict[eachKey]

...    del  myDict[eachKey]

...

c 3

b 2

d 4

>>> myDict

{}

 

        创建迭代器,对一个对象调用iter() 就可以得到它的迭代器。它的语法如下:

iter(obj)

iter(func,  sentinel)

        如果传递一个参数给 iter() ,它会检查你传递的是不是一个序列,如果是,那么很简单:根据索引从 0 一直迭代到序列结束。另一个创建迭代器的方法是使用类:一个实现了__iter__() 和 next() 方法的类可以作为迭代器使用 

        如果是传递两个参数给iter() ,它会重复地调用 func ,直到迭代器的下个值等于sentinel。一个简单的例子如下:

>>> def fun():

...     return 1

...

>>> myiter = iter(fun,  2)

>>> myiter.next()

1

>>> for i in myiter:

...     print i

1

1

1

1

1......(死循环)

 

        reversed() 内建函数将返回一个反序访问的迭代器。enumerate() 内建函数同样也返回迭代器。另外两个新的内建函数any() 和 all(),在 Python 2.5 中新增,如果迭代器中某个/所有条目的值都为布尔真时,则它们返回值为真。

 

0 0
原创粉丝点击