iterator protocol
iterator object必须实现两个method:
__iter()__
和 __next()__
注意: Python 3 中使用
__iter__()
和__next__()
;Python 2 中使用__iter__()
和next()
iterable
iterable是个名词
list, tuple, dict都是iterable
可以用for x in yyy
形式的yyy
都是一个iterable
iterator、 iter()、 next()
如果一个对象yyy是iterable,那么可以用a = iter(yyy)
获得一个iterator a
也可以用
yyy.__iter__()
再用next(a)
手动进行一次迭代/iterate
也可以用
a.__next__()
当一个iterator已经迭代到头了,下一次next()
会报StopIteration
错误
下面是一个例子
# define a list
my_list = [4, 7, 0, 3]
# get an iterator using iter()
my_iter = iter(my_list)
## iterate through it using next()
#prints 4
print(next(my_iter))
#prints 7
print(next(my_iter))
## next(obj) is same as obj.__next__()
#prints 0
print(my_iter.__next__())
#prints 3
print(my_iter.__next__())
## This will raise error, no items left
next(my_iter)
for loop的实现原理
for element in iterable:
# do something with element
对应的实现代码是:
# create an iterator object from that iterable
iter_obj = iter(iterable)
# infinite loop
while True:
try:
# get the next item
element = next(iter_obj)
# do something with element
except StopIteration:
# if StopIteration is raised, break from loop
break
构建自己的Iterator
对于一个类,只要实现__iter__()
和__next__()
方法即成为一个iterator
__iter__()
method返回iterator对象本身,同时也可以做一些初始化工作
__next__()
method返回一系列迭代值,最后通过raise StopIteration错误来结束迭代
下面的例子每次迭代返回一个2幂次方,幂指数从0一直到用户给定的值
class PowTwo:
"""Class to implement an iterator
of powers of two"""
def __init__(self, max = 0):
self.max = max
def __iter__(self):
self.n = 0
return self
def __next__(self):
if self.n <= self.max:
result = 2 ** self.n
self.n += 1
return result
else:
raise StopIteration
那么运行结果为:
>>> for i in PowTwo(5):
... print(i)
...
1
2
4
8
16
32
Infinite Iterators
迭代器可以是无限迭代的,例如依次返回所有的奇数。
不过使用时必须谨慎处理,加上适当的终止条件。
Python built-in 函数iter()
可以有两个参数
一参是一个callable object (如function)
二参是一个sentinel value (终止条件/ terminating condition)。
迭代器会调用这个function直到返回值等于sentinel value。
例如,
>>> int()
0
>>> inf = iter(int,1)
>>> next(inf)
0
>>> next(inf)
0
iter(int, 1)
返回了一个迭代器,这个迭代器遇到1时终止迭代。
注意:遇到1直接raise StopIteration,而不是下次迭代raise StopIteration
int()
(int的构造函数)永远都返回0
因此这个迭永远不会停止,即成为一个infinite iterator.