Jamal的博客

Python-迭代器

首先看一下这个文档:文档链接
从文档中有几个重要的信息:

  • 可迭代对象(Iterable):可以直接作用于for循环的对象,实现了iter()方法。
  • 迭代器(Iterator):可以被next()函数调用并不断返回下一个值的对象。
  • 生成器都是Iterator对象,但集合数据类型虽然是Iterable,却不是Iterator
  • 可以使用iter()把Iterable变成Iterator

iter()函数

iter()的定义:

1
2
3
4
5
6
7
8
9
10
def iter(source, sentinel=None): # known special case of iter
"""
iter(iterable) -> iterator
iter(callable, sentinel) -> iterator
Get an iterator from an object. In the first form, the argument must
supply its own iterator, or be a sequence.
In the second form, the callable is called until it returns the sentinel.
"""
pass
  1. iter(iterable)
    函数参数必须是可迭代对象,支持迭代器协议(iteration protocol)或者是序列协议(sequence protocol)。也就是实现了iter()方法或者getitem()方法,如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Iter1:
'''只有一个参数的情况'''
def __init__(self):
self.count = 0
def __iter__(self):
print('__iter__ is called')
self.count += 1
if self.count > 5:
raise StopIteration
return iter(self)
if __name__ == '__main__':
iter1 = Iter1()
for i in iter1: # 当执行for循环时,实际上是调用了iter1.__iter__(),也就是__iter__(iter1),返回一个iterator对象
print(i)
iter2 = Iter1()
iter22 = iter(iter2)
print(iter22.__next__())
  1. iter(callable, sentinel)
    当有两个参数的时候,则第一个参数必须是可调用的对象(实例)即定义了call方法,这时候iter会生成一个迭代器(Iterator),每次调用这个迭代器的next()方法(在python2中是next()方法),都会调用callable,如果next()方法返回等于sentinel,则抛出StopIteration报错,否则返回下一个值。如下代码:
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
class Iter2:
'''两个参数的情况'''
def __init__(self):
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
if self.count > 5:
raise StopIteration()
return self.count
def get_next(self):
self.count += 1
if self.count > 10:
raise StopIteration()
return self.count
if __name__ == '__main__':
iter3 = Iter2()
iter33 = iter(iter3, 10)
for i in iter33:
print(i)
iter4 = Iter2()
iter44 = iter(iter4.get_next, 10)
for i in iter44:
print(i)