生成器
-
在Python这门语言中,生成器毫无疑问是最有用的特性之一。与此同时,也是使用的最不广泛的Python特性之一
-
究其原因,主要是因为,在其他主流语言里面没有生成器的概念。正是由于生成器是一个“新”的东西,所以,它一方面没有引起广大工程师的重视,另一方面,也增加了工程师的学习成本,最终导致大家错过了Python中如此有用的一个特性。那到底什么是生成器呢?
-
有时候,序列或集合内的元素的个数非常巨大,如果全制造出来并放入内存,对计算机的压力是非常大的。
-
比如,假设需要获取一个10**20次方如此巨大的数据序列,把每一个数都生成出来,并放在一个内存的列表内,如果使用这种粗暴的方式,你能确保你的计算机会有如此大的内存么?
-
那么如果元素可以按照某种算法推算出来,需要该元素的话那就计算到哪个元素,那么就可以在循环的过程中不断推算出后续的元素,而不必创建完整的元素集合,从而节省大量的空间。在Python中,这种一边循环一边计算出元素的机制,称为生成器:generator。
-
因此:生成器是一种特殊的迭代器,生成器自动实现了“迭代器协议”(即__iter__和next方法),不需要再手动实现两方法。
-
-
下面,我们一起来看看如何创建一个生成器!2种方式
-
生成器推导式
-
yield关键字
-
-
生成器推导式:
-
tup = (x for x in range(3))
- 1
-
可以通过next()函数获得generator的下一个返回值:
-
next(tup)
- 1
-
但更多情况下,我们使用for循环遍历生成器:
-
for i in tup: print(i)
- 1
- 2
-
yield关键字创建生成器
-
在 Python中,使用yield返回的函数会变成一个生成器(generator)。 在调用生成器的过程中,每次遇到yield时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次执行next()方法时从当前位置继续运行。下面重点理解yield关键字的使用:
-
yield 是一个类似 return 的关键字,只是这个函数返回的是个生成器
-
当你调用这个函数的时候,函数内部的代码并不立马执行 ,这个函数只是返回一个生成器对象
-
当你使用for进行遍历的时候或者调用next函数后,函数中的代码才会执行
-
-
简单示例代码:函数体通过for循环结合yield返回一个生成器
-
def mySum(): print('before') print('after') yield 'result' f = mySum() print(f,next(f))
- 1
- 2
- 3
- 4
- 5
- 6
- 7
-
思考:下述函数的执行结果是什么?
-
def yieldTest(): i = 0 while i < 3: temp = yield i print(temp) i += 1
- 1
- 2
- 3
- 4
- 5
- 6
-
obj = yieldTest() #返回的生成器对象 print(next(obj))
- 1
- 2
-
obj = yieldTest() #返回的生成器对象 print(next(obj)) print(next(obj))
- 1
- 2
- 3
-
-
for i in yieldTest(): print(i)
- 1
- 2