生成器高级用法
生成器高级用法
1.概述
这篇文章介绍生成器的一些使用技巧,同时用它来替代传统容器实现一些好用的功能。
2.生成器
2.1.生成器介绍
生成器是python里的一种特殊的数据类型,他是一个不断给调用方生成内容的类型。定义一个生成器需要用到生成器函数与yield关键字。
1.创建一个生成器Demo
# 生成器
def generate_even(max_number):
# 一个简单的生成器,返回0到max_number之间所有的偶数
for i in range(0, max_number):
if i % 2 == 0:
yield i
# 遍历生成器对象,输出结果
for i in generate_even(100):
print(i)
# 调用next()函数可以逐步从生成器里拿到结果
g = generate_even(10)
print(next(g))
print(next(g))
print(next(g))
# 因为生成器是可迭代对象,所以可以使用容器内置函数将其转为其他容器类型。例如将它转为list容器
mylist = list(generate_even(10))
print(f'将生成器转换为list容器:type({mylist})'
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
2.2.按需返回替代容器
在Python2时代,如果用range()生成一个非常大的数字序列,速度会非常慢。这是因为range()需要组装并返回一个巨大的列表。整个计算与内存分配会耗费大量时间。
# 在python2中的range()会将结果组装的一个列表,一次性返回所有数字。
>>> range(4)
[0, 1, 2, 3]
- 1
- 2
- 3
在python3时代,调用range()瞬间就会返回结果,因为它不在返回列表,而是返回一个类型为range的惰性计算对象。
当序列过大时,新的range()函数不再会一次性耗费大量内存和时间,生成一个巨大的列表,而是仅在迭代时按需返回数字。
range()的进化虽然简单,但它代表了一个重要的编程思维——按需生成,而不是一次性返回。
虽然都是返回结果,但yield和return的最大不同之处在于,return的返回是一次性的,使用它会直接终止整个函数执行。而yield可以逐步给调用方生成结果。
# r 是range对象,而非装满数字的列表
>>> r = range(10000000)
# 只有在迭代range对象时,他才会不断生成新的数字
>>> for i in r:
>>> print(i)
- 1
- 2
- 3
- 4
- 5
3.生成器应用案例
3.1.用生成器替代列表
在写代码过程中,我们经常要处理一些数据,假如在批处理时数据量过大或者处理逻辑复杂导致处理速度很慢,例如下面的示例存在两点问题:
- 将处理后的大数据放到列表中,一次性返回占用很大的内存,同时处理速度也很慢。
- 如果函数调用方想在满足特定条件时中断,不在继续处理后面的数据,现在batch_process函数是做不到的。
def batch_process(items):
'''
批量多个items对象
:param items:
:return:
'''
result = []
for item in range(0, items):
# 假如处理item需要花费大量时间
if item % 2 == 0:
result.append(item)
# 处理的结果拼接到列表中返回
return result
process = batch_process(10)
print(process)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
为了解决上面的问题,我们可以使用生成器改写它,用yield替代列表。
def batch_yield(items):
'''
批量多个items对象
:param items:
:return:
'''
for item in range(0, items):
# 假如处理item需要花费大量时间
if item % 2 == 0:
yield item
for i in batch_yield(10):
# 满足特定条件后不在处理后面的数据
if i == 4:
break
print(i)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
文章来源: brucelong.blog.csdn.net,作者:Bruce小鬼,版权归原作者所有,如需转载,请联系作者。
原文链接:brucelong.blog.csdn.net/article/details/126567213
- 点赞
- 收藏
- 关注作者
评论(0)