生成器和迭代器

来源:互联网 发布:唯一网络怎么样 编辑:程序博客网 时间:2024/06/18 10:14

生成器generator

尽管列表解析可以方便地创建列表,但会占用内存,而且容量有限(受内存影响)。如果列表元素可以按照某种算法推算出来,那我们就可以创建生成器generator,这样就不必创建完整的list。生成的generator可以理解为iterator,用for循环来迭代它。如果推算的算法比较复杂,用类似for循环无法实现,可以用定义函数来实现。根本上来说,迭代器就是一个有nest()方法的对象。条目全部取出后,会引发一个 StopIteration 异常。生成器表达式就好像是惰性的列表解析。

语法:

(expression for iter_val in iterator)#语法与列表解析一样,只需把`[]`改成`()`。

例如计算文本文件中非空字符总和,如果用列表解析,内存性能会很低,用生成器表达式会很方便实惠:

sum(len(word) for line in date for word in line.split())

另一种创建生成器的方法:定义一个函数,采用yield语句:

aa='def'def bb():    yield 'a'    yield 'b'    yield 'c'aa_product_bb=[x+y for x in aa for y in bb()]# return ['da','db','dc','ea','eb','ec','fa','fb','fc']

这里在列表解析中,两个for循环,有一个是生成器bb(),另一个是可迭代对象。如果两个都是迭代器,就会出问题!具体的原因未知…

利用yield语句定义fibonaci数列:

def fib(max):    n,a,b=0,0,1    while n<max:        yiled b        a,b=,b,a+b        n+=1    return 'done'

函数定义中包含yield关键字,这个函数就不是一个普通的函数,而是一个generator

迭代器

可以直接用for循环作用的数据类型有:
* 集合数据类型:list,tuple,dict,set,str.
* generator: 生成器及带yield的generator function.
这些可以直接用for循环作用的对象统称为可迭代对象Iterable。可以用isinstance()判断对象是否为Iterable对象:

isinstance((x for x in range(10)),Iterable) #return True

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator.
生成器都是Iterator对象,但list,dict,str虽然是Iterable,却不是Iterator,可以利用函数iter()使它们变成Iterator.
Iterator可以表示一个无限大的数据流,且不会占用大内存。for循环本质上不断调用next(0函数实现的。

廖雪峰网站