概述
迭代意味着重复多次,就好比循环。迭代器可迭代实现了方法__iter__的所有对象。
方法__iter__返回一个迭代器,它是包含方法__next__的对象,而调用这个方法时可不提供任何参数。当你调用__next__时,迭代器应返回其下一个值。如果迭代器没有可提供返回的值,应引发StopIteration异常。还可以使用内置的便利函数next,在这种情况下,next(it)与it._next_()等效
为何不用列表
从以上对迭代器的定义,可能会联想到,为啥不直接用列表循环呢?
其实在很多情况下,使用列表都有点像用大炮打蚊子。比如说,假如你有一个可逐个计算值的函数,你可能只想逐个地获取值,而不是使用列表一次性获取。这是因为如果有很多值,列表可能占用太多的内存。
还有一个很重要的原因,使用迭代器更通用、简洁、优雅。
下面来看一个不能使用列表的示例,如果使用列表,这个列表的长度必须是无穷大的。
斐波那契数列:
class Fibs:
def __init__(self):
self.a = 0
self.b = 1
def __next__(self):
self.a,self.b = self.b,self.a+self.b
return self.a
def __iter__(self):
return self
这个迭代器实现了方法__iter__,而这个方法返回迭代器本身。在很多情况下,都在另一个对象中实现返回迭代器的方法__iter__,并在for循环中使用这个对象。但推荐在迭代器中也实现方法__iter__(并像上面那样让它返回self),这样迭代器就可以直接用于for循环中。
更正规的定义是,实现了方法__iter__的对象是可迭代的,实现了方法__next__的对象是迭代器。
接下来创建以上示例中类的对象,并使用:
fibs = Fibs()
for f in fibs:
if(f > 2000):
print(f)
break
这里是为了找出一个大于2000的斐波那契数。
这个循环之所以会停止,是因为其中包含了break语句,否则,这个for循环将会一直执行下去。
通过iter获得迭代器
除以上方式外,还可以通过对可迭代对象调用内置函数iter,可获得一个迭代器。
比如:
it = iter([1,2,3,4])
print(next(it))
print(next(it))
输出:
1
2
从迭代器创建序列
除了对迭代器和可迭代对象进行迭代之外,还可以将他们转换成序列。在可以使用序列的情况下,大多也可以使用迭代器或可迭代对象。
示例,使用构造函数list显式地将迭代器转换成列表。
class TestIterator(object):
"""docstring for TestIterator"""
value = 0
def __next__(self):
self.value += 1
if self.value > 10:
raise StopIteration
return self.value
def __iter__(self):
return self
ti = TestIterator()
print(list(ti))
输出:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]