什么是迭代器
相关概念定义
迭代器(Iterator):
满足迭代协议的对象就是迭代器
iterator就是实现了Iteration Protocol的对象,这类对象都支持循环遍历的操作(for/while/支持迭代的函数list() sum()…)。
迭代协议(Iteration Protocol):
内建函数iter()
接收一个可迭代对象,并返回一个可迭代对象.
每次将这个可迭代对象传递给next()
函数,都会返回它所包含的下一个元素,当迭代完最后一个元素时,就会触发StopIteration异常。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
>>> x = iter([1, 2, 3]) >>> x <listiterator object at 0x1004ca850> >>> next(x) 1 >>> next(x) 2 >>> next(x) 3 >>> next(x) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration |
满足以上要求的对象,就是迭代器。
迭代隐含的操作
在每次的迭代语句中,python都会按照迭代协议去对迭代器进行迭代。其实,在实际执行中,python会进行一些其他的操作:
- 将需要迭代的对象作为参数传递给
iter
函数 iter
返回一个迭代器对象- 每次循环则将返回的迭代器对象传递给
next
函数 - 循环至最后一个元素,触发
StopIteration
以for语句为例:
当我们在Python中执行循环语句for i in foo
的时候,其背后的操作是:
- foo = iter(foo)
- next(foo)
next(foo)在python3中执行的是:foo.__next__()
,在python2中则是:foo.next()
迭代器的实现
迭代器是用class来实现的。其中必需实现的有两个方法:__iter__
、next
(python2)/__next__
(python3)。其中,__iter__
必需返回一个迭代器对象,next
则负责迭代逻辑并在迭代完毕时触发异常。
如下:
1 2 3 4 5 6 7 8 9 |
def Iter(object) def __init__(self): pass def __iter__(self): pass def __next__(self): # python3 pass def next(self): # python2 pass |
迭代器的特殊情况
迭代器的__iter__
返回self
迭代器的__iter__
方法需要返回的是一个具有next
方法的可迭代对象。如果当__iter__
返回的是self
的话,就会产生其他意想不到的效果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
class yrange: def __init__(self, n): self.i = 0 self.n = n def __iter__(self): return self def next(self): if self.i < self.n: i = self.i self.i += 1 return i else: raise StopIteration() class zrange: def __init__(self, n): self.i = 0 self.n = n def __iter__(self): return zrange(self.n) def next(self): if self.i < self.n: i = self.i self.i += 1 return i else: raise StopIteration() |
执行结果:
1 2 3 4 5 6 7 8 9 10 |
>>> y = yrange(5) >>> list(y) [收一个可迭代对象,并返回一个可迭代对象. 每次将这个可迭代对象传递给 next() 函数,都会返回它所包含的下一个元素,当迭代完最后一个元素时,就会触发StopIteration异常。
满足以上要求的对象,就是迭代器。 迭代隐含的操作在每次的迭代语句中,python都会按照迭代协议去对迭代器进行迭代。其实,在实际执行中,python会进行一些其他的操作:
以for语句为例:
next(foo)在python3中执行的是: 迭代器的实现迭代器是用class来实现的。其中必需实现的有两个方法: 如下:
迭代器的特殊情况迭代器的
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
class yrange: def __init__(self, n): self.i = 0 self.n = n def __iter__(self): return self def next(self): if self.i < self.n: i = self.i self.i += 1 return i else: raise StopIteration() class zrange: def __init__(self, n): self.i = 0 self.n = n def __iter__(self): return zrange(self.n) def next(self): if self.i < self.n: i = self.i self.i += 1 return i else: raise StopIteration() |
执行结果:
1 2 3 4 5 6 7 8 9 10 |
>>> y = yrange(5) >>> list(y) [/span>0, 1, 2, 3, |