迭代器(iterator)是一个实现了迭代器协议的对象,python的一些内置数据类型(列表,数组,字符串,字典等)都可以通过for语句进行迭代,我们也可以自己创建一个容器,实现了迭代器协议,可以通过for,next方法进行迭代,在迭代的末尾,会引发stopIteration异常。
In [14]: it = range(2)
In [15]: ite = iter(it)
In [16]: ite.next()
Out[16]: 0
In [17]: ite.next()
Out[17]: 1
In [18]: ite.next()
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-18-887aa41fdfa0> in <module>()
----> 1 ite.next()
StopIteration:
自己实现及使用迭代器:为容器对象添加iter(),_next()方法,在调用时,可以通过next以及for循环
class PythonLearn:
def __init__(self, start = 0, stop = 0):
self.start = start
self.stop = stop
def __iter__(self):
print('call __iter__')
return self
def next(self):
print("call __next__")
if self.start < self.stop:
i = self.start
self.start += 1
return i
else:
raise StopIteration
if __name__ == '__main__':
learn = PythonLearn(2,5)
next(learn)
print(next(learn))
for i in learn:
print i
运行结果:
call __next__
call __next__
3
call __iter__
call __next__
4
call __next__
生成器(generator)是通过yield语句快速生成迭代器,可以不用iter和next方法
yield可以使一个普通函数变成一个生成器,并且相应的next()方法返回是yield后的值。一种更直观的解释是:程序执行到yield时会返回结果并暂停,再次调用next时会从上次暂停的地方继续开始执行。
显然,生成器自身有构成一个迭代器,每次迭代时使用一个yield返回 的值,一个生成器中可以有多个yield的值
In [21]: def test():
....: yield 1
....: yield 3
....: yield 22
....:
In [22]: a = test()
In [23]: type(a)
Out[23]: generator
In [24]: a.next()
Out[24]: 1
In [25]: a.next()
Out[25]: 3
In [26]: a.next()
Out[26]: 22
xrange 和range的区别
In [9]: xrange(5)
Out[9]: xrange(5)
In [10]: range(5)
Out[10]: [0, 1, 2, 3, 4]
In [11]: list(xrange(5))
Out[11]: [0, 1, 2, 3, 4]
In [12]: print type(xrange(4))
<type 'xrange'>
In [13]: print type(range(4))
<type 'list'>
range(1000)会返回一个长度为1000的数组,而xrange(1000)会返回一个生成器,在需要的情况下返回一个数字,此时空间的占用情况会大为减少。所以为了提升性能,在做循环的时候,应该尽可能的使用xrange,除非需要用range返回一个数组。
参考资料:
http://python.jobbole.com/84527/
http://www.cnblogs.com/coder2012/p/4305935.html