Python学习-39.Python中的生成器
先回顾列表解释
1 lista = range(10) 2 listb = [elem * elem for elem in lista]
那么listb就将会是0至9的二次方。
现在有这么一个需求,需要存储前10个斐波那契数到硬盘。
那么先写产生斐波那契数的函数:
1 def fib(max): 2 n,a,b = 0,0,1 3 while n < max: 4 print(b) 5 a,b = b,a + b 6 n+=1
这样就会打印出前max个斐波那契数了。接着我们再修改一下。(因为我们需要的是存到硬盘里)
1 fiblist = [] 2 def fib(max): 3 n,a,b = 0,0,1 4 while n < max: 5 fiblist.append(b) 6 a,b = b,a + b 7 n+=1 8 9 fib(10) 10 print(fiblist)
接下来就可以操作fiblist保存到硬盘里了。
这样做可能我们操作前10个、前100个或许没有问题,但是假如某天业务需求要存十万个那就倒霉了。fiblist的长度得要十万,内存都撑不下了。这怎么办,直接修改fib函数,让其直接写入硬盘而不是追加到列表?但如果某天业务逻辑又改了怎么办,不存硬盘了,存数据库了。这显然不是好办法。
Python中有一个关键字,叫yield,就是可以解决这种问题的。
修改代码:
1 def fib(max): 2 n,a,b = 0,0,1 3 while n < max: 4 yield b 5 a,b = b,a + b 6 n+=1 7 8 temp = fib(10) 9 print(temp)
现在,输出的则变成了<generator object fib at 0x0354FC10>
PS:at后面的0x部分可能有不同。
这是什么东西呢?这就是Python中的生成器。也就是一个可遍历对象。
既然可遍历,那么我们就可以使用for语句了
1 def fib(max): 2 n,a,b = 0,0,1 3 while n < max: 4 yield b 5 a,b = b,a + b 6 n+=1 7 8 for i in fib(10000): 9 #do something 10 pass
现在该干什么就干什么吧,内存不会撑爆了。
另外,Python中的列表解释还能够快速改为生成器:
1 l = [elem * elem for elem in range(10)]
这是列表解释,而改为生成器:
1 g = (elem * elem for elem in range(10))
区别就只是将[]改为()
总结:
生成器就像是C#中的IEnumerable接口(这并不准确,准确是含GetEnumerator的方法)