python迭代器(Iterator)

迭代器(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 "", line 1, in 
File "", line 11, in next
StopIteration
>>> next(c)
Traceback (most recent call last):
File "", line 1, in 
File "", 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))