在学习迭代器与生成器的时候,感觉很难理解它们的原理,特别是迭代器与for循环的结合,与C的for循环有很大不同,思维转不过来。在网上查了很大资料,对此有了一定的了解,下面部分是网上的资料,部分是我的个人理解。
一、迭代器
1、迭代器规则
迭代的意思是重复做一些事情很多次,到现在为止只是在for循环中对序列和字典进行迭代,但实际上也能对其他的对象进行迭代:实现__iter__方法的对象。
__iter__方法返回一个迭代器,所谓迭代器就是具有next方法(这个方法在调用时不需要任何参数)的对象。在调用next方法时,迭代器会返回它的下一个值。如果next方法被调用,但迭代器没有值可以返回,就会引发一个StopIteration异常。
为什么不用列表?列表是一次性获取所有值的,如果有很多值,列表会占用太多的内存,但是迭代器可以在使用时计算一个值时获取一个值,使用迭代器更通用,简单,优雅。
__metaclass__ = type
class Fibs:
def __init__(self):
self.a = 0
self.b = 0
def next(self):
self.a,self.b = self.b,self.a + self.b
return self.a
def __iter__(self):
return self
>>> f = Fibs()
>>> for n in f:
if n > 10:
print n
break
上面的例子中,f对象在for循环中每次循环都会先调用next方法,然后n得到self.a的值,最后iter返回self。于是每次循环n的值都在f对象的值域内,因此这是个死循环。后面有个break,所以运行时并不会无限循环。
以上是我对迭代器在for循环中工作流程的理解,如有错误,请务必指出。
2、 从迭代器得到序列
__metaclass__ = type
class 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()
>>> list(ti)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
二、生成器
我的理解是:生成器在每次yield之后都会返回一个迭代值,然后冻结函数,等待下一次迭代开始,函数会从冻结的地方(即yield处)继续开始执行函数。
这个部分有一篇文章讲解的特别好,我直接转载过来了,原文链接:http://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/
您可能听说过,带有 yield 的函数在 Python 中被称之为 generator(生成器),何谓 generator ?
我们先抛开 generator,以一个常见的编程题目来展示 yield 的概念。
如何生成斐波那契數列
斐波那契(Fibonacci)數列是一个非常简单的递归数列,除第一个和第二个数外,任意一个数都可由前两个数相加得到。用计算机程序输出斐波那契數列的前 N 个数是一个非常简单的问题,许多初学者都可以轻易写出如下函数:
清单 1. 简单输出斐波那契數列前 N 个数
def fab(max): n, a, b = 0, 0, 1 while n < max: print b a, b = b, a + b n = n + 1
执行 fab(5),我们可以得到如下输出: