在列表、字符串等的使用过程中,我们的数据都是一次性生成到内存中的。这很消耗内存空间,对此,可以使用生成器来降低内存消耗。
P 生成器定义
python提供两种生成器,一种是生成器表达式、一种是生成器函数。
(1)生成器表达式
生成器表达式会产生一个新的生成器对象。 其句法与推导式相同,区别在于它是用圆括号而不是用方括号或花括号括起来的。
gen = (x for x in range(5))type(gen)# 输出:generator
(2)生成器函数
在一个函数体内使用 yield 表达式会使这个函数变成一个生成器函数(本文重点),而在一个 async def 函数的内部使用它则会让这个协程函数变成一个异步生成器函数(本文不讲异步)。
# 定义生成器函数 def gen(obj): for i in obj: yield i# 生成器制作一个数据 a = gen([1,2,3])print(type(a))# 输出:generator
P 生成器使用
生成器使用时会逐一生成数据,不会占用大量的内存空间(节省内存),这也是为什么需要使用生成器的原因。
如下是使用生成器的示例:
a = gen([1,2,3])# 读取生成器数据 print(next(a)) # 输出:1print(next(a)) # 输出:2print(next(a)) # 输出:3print(next(a))# 输出(表示生成器没有数据了):# Traceback (most recent call last):## Cell In[45], line 1# next(a)##StopIteration
现在让我们来看看内存占用情况,如下:
# 导入包,用于查看变量的内存占用情况 import sys# 生成器和列表记录5个整数lst = list(range(5))g = gen(lst)print('列表占用内存{0}个字节'.format(sys.getsizeof(lst)))print('生成器占用内存{0}个字节'.format(sys.getsizeof(g)))# 输出 :# 列表占用内存104个字节# 生成器占用内存200个字节
上述可以看到列表占用内存104个字节,生成器占用200个字节。现在,我们将数据扩大到1000个整数看看,如下:# 生成器和列表记录1000个整数lst = list(range(1000))g = gen(lst)print('列表占用内存{0}个字节'.format(sys.getsizeof(lst)))print('生成器占用内存{0}个字节'.format(sys.getsizeof(g)))# 输出:# 列表占用内存8056个字节# 生成器占用内存200个字节
上述可以看到列表占用内存8056个字节,而生成器依然只占用200个字节。这里可以看到生成器的优势,它的内存占用不会随数据量的多少变动,这在内存紧张的场景下极为重要。
-------------------------它是数字世界里的一把杀猪刀
却总能巧夺天工
它的世界是纯粹0、1组合
却总能创造无尽幻想
......
本公众号关注数据价值分析、编程学习,将不定期更新社会热点数据分析结果、编程技巧,分享数据分析工具、方法、学习等内容,欢迎有兴趣的小伙伴加入。