由来
列表储存大量数据,很占内存。
而generator不怎么占计算机资源。
简单的生成器
生成一个生成器,注意是 ( )
gen = (x for x in range(3))
print(gen)
结果:这是一个生成器对象 at 什么地址。
<generator object <genexpr> at 0x0000020425156A50>
如何调用?
法一:
for item in gen:
print(item)
#output:
0
1
2
for循环这说明生成器是可迭代的,more precisely,生成器是一个迭代器
str,list,tuple,dict,set这些都是可迭代的,就是可用for来访问里面的每一个元素。但他们并不是迭代器。
法二:
print(next(gen))#output:0
print(next(gen))#output:1
print(next(gen))#output:2
print(next(gen))#output:Traceback (most recent call last):StopIteration
到第四个print(next(gen))时,系统告诉我们停止迭代。也就是gen迭代到最后了,无法继续迭代了
逐个生成(0,1,2),在某个条件下就返回一个结果给调用者,而不是全部实现后再一个个迭代出来,that‘s why我们用next(gen)
如何定义一个自己的生成器函数——yield 关键词
用( )来创建一个生成器。用yield这个关键词,功能类似return,返回一个值给调用者,只不过有yield的函数返回值后函数依然保持调用yield时的状态,当下次调用的时候,在原先的基础上继续执行代码,直到遇到下一个yield或者满足结束条件结束函数为止。
例如:下面的代码可以反复调用4次generator函数。(最后一次StopIteration)
def generator():
yield "a"
yield "b"
yield "c"
for i in generator():
print(i);
输出
a
b
c
总结
假如我们定义了一个函数(这个特殊的函数就似乎迭代器),包含多个步骤的方法封装进这个函数。每一次调用这个函数就返回一个步骤,并保存好当前执行到哪个状态。如果中途有事,比如我们执行到步骤二的时候突然去做别的事,回来调用这个函数就会得到步骤三,也就是状态保存好了。我们可以执行这个函数(迭代器)直到调用完所有步骤为止。
定义一个方法,这个方法是一步步执行的,并能保存状态,这就是迭代器。
generator是一种特殊的函数,和一般的函数不同:
一般的函数调用一次,总会结束返回;
generator却可以执行到某个位置停住,通过yield让出执行权,下次再调用时,从上一次yield后面的地方开始执行。
后记
用生成器可以无限穷举,比如,杨辉三角。
彩蛋
jieba.cut
以及 jieba.cut_for_search
返回的结构都是一个可迭代的 generator,可以使用 for 循环来获得分词后得到的每一个词语(unicode)
(⊙o⊙) !!!!!