美文网首页Python 运维
python迭代器(Iterator)

python迭代器(Iterator)

作者: 王吉吉real | 来源:发表于2017-11-09 20:50 被阅读0次

    迭代器(iterator)是实现了迭代协议(Iteration Protocol)对象。迭代协议包括两个方法:

    • __iter__,该方法返回一个迭代器, 可用于for循环;

    • __next__,该方法返回迭代器里下一个元素,并且一个元素只返回一次,当没有元素可返回时,引发一个StopIteration异常;

    class Iterator_obj(object):
    
        def __init__(self, start, end):
            self.low = start
            self.high = end
    
        def __iter__(self):
            return self
    
        def next(self):
    
            if self.low > self.high:
                raise StopIteration
            else:
                self.low += 1
                return self.low - 1
    
    a = Iterator_obj(1, 10)
    
    for i in a:
        print i
    
    

    迭代器遍历一次,一旦开始引起StopIteration异常,再调用next会一直引起该异常。

    >>>a = Iterator_obj(1, 2)
    >>>next(a)
    1
    >>>next(a)
    2
    >>>next(a)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 11, in next
    StopIteration
    >>> next(c)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 11, in next
    StopIteration
    

    注:python中的for循环其实是使用迭代器,转化成了while循环的方式使用的。

    迭代器与可迭代对象是有区别的。可迭代对象是可以被for循环遍历的对象,比如列表、字符串,字典等,但是列表、字符串、字典却没有实现迭代器协议。

    >>> a = [1, 2, 3]
    >>> for i in a:
    ...     print(i)
    ... 
    1
    2
    3
    >>> dir(a)
    ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
    

    列表并没有实现迭代器协议,但可以被for循环遍历
    在python中,文件可以使用for循环遍历,实现了迭代器协议。在for循环对文件进行遍历的时候,它并不知道是在遍历文件,而是使用迭代器协议去访问访问对象。

    >>> f = open('/etc/hosts')
    >>> dir(f)
    ['__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'closed', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines', 'xreadlines']
    

    另外,python中许多内置函数也是通过迭代协议访问对象的。

    标准库中的itertools模块使用迭代器的工具,下面是列举其中的几个:
    chain--将多个迭代器连接成一个

    >>> import itertools
    >>> iter1 = iter([1, 2, 3])
    >>> iter2 = iter([4, 5, 6])
    >>> list(itertools.chain(iter1, iter2))
    [1, 2, 3, 4, 5, 6]
    

    izip--返回迭代器版本的zip

    >>> for i,j in itertools.izip(x,y):
    ...     print i, j
    ... 
    1 5
    2 5
    3 6
    4 7
    

    enumerate--以可迭代对象为参数,返回以数据源中(索引,取值)为元素的迭代器

    >>> a = ["a","b","c"]
    >>> for i, j in enumerate(a):
    ...     print i, j
    ... 
    0 a
    1 b
    2 c
    

    相关文章

      网友评论

        本文标题:python迭代器(Iterator)

        本文链接:https://www.haomeiwen.com/subject/wgimmxtx.html