zoukankan      html  css  js  c++  java
  • Python基础:07迭代器

            迭代器是在版本 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 中新增,如果迭代器中某个/所有条目的值都为布尔真时,则它们返回值为真。

     

  • 相关阅读:
    POJ2355 Railway tickets DP优化
    POJ3280 Cheapest Palindrome 区间DP
    POJ2352 Stars 线段树
    适牛的类岛娘头文件<转载>
    Ural 1519 Formula 1 插头DP(单回路)
    POJ3345 Bribing FIPA 树形DP+分组背包
    6个变态的C语言HelloWorld程序<转载>
    POJ2374 Fence Obstacle Course DP+线段树优化
    POJ3133 Manhattan Wiring 插头DP
    ACdream 完美数 数位DP
  • 原文地址:https://www.cnblogs.com/gqtcgq/p/7247209.html
Copyright © 2011-2022 走看看