Python自学成才之路 生成器的使用
为何需要生成器? 假如现在有一个需求,需要打印从1到1亿的整形。如果我们采用普通的方式,直接调用range函数,那么程序肯定会崩溃,因为range(1,100000000)函数直接产生一个从1-1亿的列表,这个列表中的所有数据都是存放在内存中的,会导致内存爆满。这时候我们可以采用生成器来解决这个问题,生成器不会一次性把所有数据都加载到内存中,而是在循环的时候临时生成的,循环一次生成一个,所以在程序运行期间永远都只会生成一个数据,从而大大节省内存。
生成器是什么? 使用yield的函数是生成器,生成器是一个迭代器。
创建一个生成器 在函数中使用yield来创建一个生成器。如下所示:
def my_gen(start, end):
index = start
while index < end:
yield index
index += 1
print(isinstance(my_gen(1, 100), Iterable))
ret = my_gen(1, 10)
for x in ret:
print(x)
怎么去理解生成器呢?可以理解为每次使用next获取生成器的值的时候会在yield出暂停并返回值,再次使用next取数时从yiled处开始执行。所以next会在yield处暂停,也在yield处被唤醒。
Send函数 send方法和next方法类似,可以用来触发生成器的下一个yield,但是send不仅可以触发下一个yield,还可以发送数据过去,作为yield表达式的值,yield表达式的值是None。
def my_gen(start):
while start < 10:
temp = yield start
print(temp)
start += 1
ret = my_gen(1)
# 在迭代开始的地方使用send只能传递None为参数
print(ret.send(None))
print(next(ret))
print(next(ret))
print(ret.send("hello"))
print(next(ret))
注意:使用send的时候,在迭代开始的地方使用send只能传递None为参数。
提前终止生成器 return语句会触发StopIteration异常,可以提前终止生成器。
def my_gen(start):
while start < 3:
yield start
start += 1
return "hello"
# 如果使用for遍历 不会出现StopIteration异常
ret = my_gen(1)
iter = my_gen(1)
while True:
print(next(iter))
输出:
Traceback (most recent call last):
File "D:/pycharm workspace/oopdemo/iterator_generator/generator_demo01.py", line 58, in <module>
print(next(iter))
StopIteration: hello
1
注意:使用next会抛出StopIteration异常,for循环遍历不会抛出StopIteration异常。
生成器的应用 使用生成器创建一个斐波拉契数列。
def fib(count):
a, b = 0, 1
tmp = 1
while tmp <= count:
yield b
c = b
b = a + b
a = c
tmp += 1
for x in fib(7):
print(x)
上面是生成器的常见的用法,实际上生成器还有一些高级的用法,后面会结合一些场景做介绍。
本人是做大数据开发的,在微信上开了个个人号,会经常在上面分享一些学习心得,原创文章都会首发到公众号上,感兴趣的盆友可以关注下哦!
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 新人赛《金融风控贷款违约》避坑指南!
- codeforces 911C (找规律)
- 4C - Registration System (Map)
- HDU5269 (字典树)
- Shaolin(map)
- 189A Cut Ribbon(dp)
- codeforces 1379A(暴力)
- codeforces 1374D(数学)
- Yet Another Walking Robot (Map)
- HDU 1059(多重背包)
- 扩散(二分答案+并查集)
- JAVA入门学习十二
- YOLO算法最全综述:从YOLOv1到YOLOv5
- codeforce893C (并查集)
- codeforces 544C(完全背包求方案数)