Python学习之路 - yield生成器,迭代器

生成器

把结果保存成生成器的状态,普通的函数中出现yield,就变成生成器。 

1、Python 3.3 中 xrange已合并到range.

1 i = range(10)
2 print (i)
3 
4 =>range(0, 10)

2. yield 生成器.

 1 def func():
 2     print(111)
 3     yield 1
 4     print(222)
 5     yield 2
 6     print(333)
 7     yield 3
 8     return "done"
 9 
10 k = func()
11 for j in k:
12      print(j)
简易的yield生成器

在 for 循环执行时,每次循环都会执行 func 函数内部的代码,执行到 yield 时,fab 函数就返回一个yield 后面的值,再次迭代时,代码从该 yield 的下一条语句继续执行,直到再次遇到 yield。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的值。

除for循环外,也可以用 k.__next__() 依次取出生成器中的值。

 

迭代器

可以直接作用于for循环的数据类型有以下几种:

一类是集合数据类型,如listtupledictsetstr等;

一类是generator,包括生成器和带yield的generator function。

这些可以直接作用于for循环的对象统称为可迭代对象:Iterable

而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

1 #判断一个对象是否是Iterable对象
2 from collections import Iterable
3 print(isinstance([],Iterable)) => True
4 print(isinstance((x for x in range(10)),Iterable)) =>True
#判断一个对象是否是Iterator对象
from collections import Iterator
print(isinstance([],Iterator)) =>False
print(isinstance((x for x in range(10)),Iterator)) =>True
#把可迭代对象转换成迭代器
from collections import Iterator
print(isinstance(iter([]),Iterator)) =>True

你可能会问,为什么listdictstr等数据类型不是Iterator

这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

 

学习内容来自:http://www.cnblogs.com/alex3714/articles/5765046.html

posted @ 2017-03-11 21:05  耕耘的小白  阅读(172)  评论(0编辑  收藏  举报