如果你有坚定的信念你就不会迷茫。
Python: yield, iterator
上一篇 /
下一篇 2010-10-12 10:39:22
/ 个人分类:Python
看到有很多人为
yield写过blog. 其实我觉得就yield而言没有什么太多可以讲的。所以想把yield, generator,
iterator一起来讲讲。
iterator,
这个就是一个对象,实现了函数__iter__()和next()的对象。他不需要继承什么父类,只需要实现这两个函数的对象我们就可以把它当作
iterator来使用。如果要打印一串数,从0,1开始,后面的数是前面两个数的和(斐波那契数列)。这个时候我们可以很好的使用iterator来实
现:
创建一个iterator类Fib,因为Fib类实现了函数__iter__()和next(),则被认为是一个iterator对象,可以通过for n
in fib 来读取fib内的对象。每一次n都是从fib中取出一个值,然后再通过next函数取下面的值,一直这样下去。
- class Fib:
- def __init__(self, max):
- self.max = max
-
- def __iter__(self):
- self.a = 0
- self.b = 1
- return self
-
- def next(self):
- fib = self.a
- if fib > self.max:
- raise StopIteration # 如果已经大于最大值则抛出StopIteration异常
- self.a, self.b = self.b, self.a + self.b # 在return之前将self的值更新
- return fib
-
- if __name__=="__main__":
- fib = Fib(1000)
- for n in fib:
- print n
在上面的代码中我们可以看到,next函数中,必须要申明fib变量来保存self.a的值,然后才可以将self.b的值付给self.a.
那如果我们使用yield返回来获得一个iterator则可以不用如此麻烦了,通过使用yield,fib函数可以认为是生成了一个generator. 这里我们每次返回了a以后,保留当前的状态继续执行一直到函数结束。所以我们不需要什么临时值,只需要在返回a后再执行即可
- def fib(max):
- a, b = 0, 1
- while a < max:
- yield a
- a, b = b, a + b
-
-
- for n in fib(1000):
- print n
相比较list与iterator,可以知道iterator是不需要实现保存所有数据的,可以返回一个值处理一个。这样对于大数据量的时候可以节约很多内存。这大概就是在python3中range被xrange取代的原因吧。
收藏
举报
TAG:
Python
python
yield
iterator