一、生成器
2.1 定义
在python中,一边循环一边计算的机制,称为生成器(generator)。之所以需要生成器,是因为其本身具备的优秀性质:
- 节约内存,python在使用生成器时对延迟操作提供了支持。所谓延迟,是指在需要的时候才产生结果,而不是立即产生结果。这样在需要的时候才去调用结果,而不是将结果提前存储起来要节约内存。比如以列表的形式存放较大数据将会占用不少内存,使用生成器来调取数据结果而不是列表来处理数据,因为这样可以节约内存。
- 迭代到下一次的调用时,所使用的参数都是上一次所保留下的。
2.2 创建生成器
2.2.1 生成器表达式
生成器表达式与列表推导式在形式上很类似,只是生成器表达式使用括号”()”来构建,使用next()来调用:
# 列表推导式:会一次性返回所有结果
t = [i**2 for i in range(5)]
# 生成器表达式:每调用一次next()返回一个,直至it为空
it = (i**2 for i in range(5))
next(it)
2.2.2 生成器函数
生成器函数使用yield返回值,不是return。yield语句每次返回一个结果,并挂起函数的状态,以便下次从它离开的地方继续执行。
def odd():
n=1
while True:
yield n
n+=2
odd_num=odd() # 调用生成器函数,odd_num为生成器对象:<generator object odd at 0x1098e5750>
count=0
for o in odd_num:
if count >=5:
break
print(o)
count += 1
2.2.3 next()与send()方法
我们先看一个生成斐波纳契数列例子:
def fib(times):
n = 0
a,b = 0,1
while n < times:
yield b
a,b = b,a + b
n += 1
return "done"
f = fib(5)
for x in f:
print(x)
next() 方法和next的作用是一样的,f.next() 和 next(f) 是作用是一样的。如下所示
def fib(times):
n=0
a,b=0,1
while n < times:
yield b
a,b=b,a+b
n+=1
f = fib(5)
for i in range(5):
print(f.__next__())
再来看看send()的作用:
def fib(times):
n = 0
a,b = 0,1
while n < times:
temp = yield b
print(temp)
a,b = b,a+b
n += 1
f = fib(5)
print(f.__next__())
print(f.send("haha"))
print(f.send("lalala"))
其结果为:
1
haha
1
lalala
2
[Finished in 0.3s]