为什么需要生成器
假如要输入1-1亿的数字, 我们采用range的方式生成数据, 那么程序就会崩溃
采用生成器的方式可以解决这个问题, 生成器不会一次把所有的数据加载到内存中, 而是在循环时临时生成的, 循环一次生成一次, 所以程序运行期间永远只能生成一个数据, 从而大大的节省了内存
解决输入1-1亿数字的问题
生成器使用'()'格式
调用__next__方法,依次输入生成器中的一个数据
list_num = (i for i in range(1, 100000000))
print(type(list_num)) # class 'generator'
print(list_num.__next__())
for i in list_num:
print(i)
next函数和__next__方法:
next函数next函数和__next__方法可以迭代生成器的返回值
list_num = (i for i in range(1, 100000000))
print(type(list_num)) # class 'generator'
print(list_num.__next__())
yield表达式
-
生成器可以通过函数产生, 如果在一个函数中出现了yield表达式, 那么这个函数不再是普通的函数, 而是一个生成器函数
-
yield函数一次返回一个结果, 并且会冻结当前函数的状态
-
例子2: 使用函数式编程实现输出1-1亿的数字
def my_gen(start, end):
index = start
while index <= end:
yield index
index += 1
res = my_gen(1, 1000000)
for i in res:
print(i)
send方法
send方法和next方法类似, 可以触发生成器的下一个yield, 但是send还可以发送数据作为yield的值
send方法第一次触发发送的值必须是None
- send方法和next方法的区别
- send方法可以传递值给yield表达式, 而next不可以
- 在第一次执行生成器代码时, send函数必须要传一个None进去
生成器异常StopIterator
- 如果生成器中值被取完了会抛出异常
- 如果出现了return语句也会触发异常
list_num = (i for i in range(1, 2))
print(type(list_num)) # class 'generator'
print(list_num.__next__())
try:
print(list_num.__next__())
except StopIteration:
print('quit')
生成器小案例
- 斐波拉契算法
# 0 1 1 2 3 5 8
def fib(count):
"""
:param count: 需要生成多少个数字
:return:
"""
index = 0
a = 0
b = 1
print(a)
while index < count:
print(b)
c = b
b = a + b
a = c
index += 1
fib(10)
- 使用yield优化
来源:CSDN
作者:仰望着那高处的巨人们
链接:https://blog.csdn.net/weixin_44737646/article/details/104128931