• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

python3使用迭代生成器实现减少内存占用

python 搞代码 4年前 (2022-01-09) 31次浏览 已收录 0个评论

技术背景

在python编码中for循环处理任务时,会将所有的待遍历参量加载到内存中。其实这本没有必要,因为这些参量很有可能是一次性使用的,甚至很多场景下这些参量是不需要同时存储在内存中的,这时候就会用到本文所介绍的迭代生成器yield。

基本使用

首先我们用一个例子来演示一下迭代生成器yield的基本使用方法,这个例子的作用是构造一个函数用于生成一个平方数组。在普通的场景中我们一般会直接构造一个空的列表,然后将每一个计算结果填充到列表中,最后return列表即可,对应的是这里的函数square_number。而另外一个函数square_number_yield则是为了演示yield而构造的函数,其使用语法跟return是一样的,不同的是每次只会返回一个值:

# test_yield.py

def square_number(length):
    s = []
    for i in range(length):
        s.append(i ** 2)
    return s

def square_number_yield(length):
    for i in range(length):
        yield i ** 2

if __name__ == '__main__':
    length = 10
    sn1 = square_number(length)
    sn2 = square_number_yield(length)
    for i in range(length):
        print (sn1[i], '\t', end='')
        print (next(sn2))

在main函数中我们对比了两种方法执行的结果,打印在同一行上面,用end=”指令可以替代行末的换行符号,具体执行的结果如下所示:

[dechin@dechin-manjaro yield]$ python3 test_yield.py <a style="color:transparent">来@源gao*daima.com搞@代#码网</a>
0       0
1       1
4       4
9       9
16      16
25      25
36      36
49      49
64      64
81      81

可以看到两种方法打印出来的结果是一样的。也许有些场景下就是需要持久化的存储函数中返回的结果,这一点用yield也是可以实现的,可以参考如下示例:

# test_yield.py

def square_number(length):
    s = []
    for i in range(length):
        s.append(i ** 2)
    return s

def square_number_yield(length):
    for i in range(length):
        yield i ** 2

if __name__ == '__main__':
    length = 10
    sn1 = square_number(length)
    sn2 = square_number_yield(length)
    sn3 = list(square_number_yield(length))
    for i in range(length):
        print (sn1[i], '\t', end='')
        print (next(sn2), '\t', end='')
        print (sn3[i])

这里使用的方法是直接将yield生成的对象转化成list格式,或者用sn3 = [i for i in square_number_yield(length)]这种写法也是可以的,在性能上应该差异不大。上述代码的执行结果如下:

[dechin@dechin-manjaro yield]$ python3 test_yield.py 
0       0       0
1       1       1
4       4       4
9       9       9
16      16      16
25      25      25
36      36      36
49      49      49
64      64      64
81      81      81

进阶测试

在前面的章节中我们提到,使用yield可以节省程序的内存占用,这里我们来测试一个100000大小的随机数组的平方和计算。如果使用正常的逻辑,那么写出来的程序就是如下所示(关于python内存占用的追踪方法,可以参考这一篇博客):

# square_sum.py

import tracemalloc
import time
import numpy as np
tracemalloc.start()

start_time = time.time()
ss_list = np.random.randn(100000)
s = 0
for ss in ss_list:
    s += ss ** 2
end_time = time.time()
print ('Time cost is: {}s'.format(end_time - start_time))

snapshot = tracemalloc.take_snapshot()
top_stats = snapshot.statistics('lineno')

for stat in top_stats[:5]:
    print (stat)


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:python3使用迭代生成器实现减少内存占用
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址