龙空技术网

技能分享:如何用生成器减少内存占用,让Python代码运行更快?

溪亭说科技 163

前言:

当前姐妹们对“python 减少内存占用”大致比较注重,同学们都想要分析一些“python 减少内存占用”的相关内容。那么小编同时在网上汇集了一些对于“python 减少内存占用””的相关内容,希望姐妹们能喜欢,看官们快快来了解一下吧!

全文共2424字,预计学习时长7分钟

图源:Unsplash

如何使用生成器减少内存占用并让Python代码运行更快,关乎你“代码人生”的生死存亡。

然而,当我刚开始学习Python生成器时,并不知道它最后会显得如此重要。


但在学习机器学习的过程中需要编写自定义函数时,它发挥了不可取代的作用。


生成器函数允许声明一个类似于迭代器的函数,使得程序员可以以快速,简便和简洁的方式创建一个迭代器。


迭代器是一个可以进行迭代的对象,用于对一个数据容器进行抽象,使其表现得像可迭代的对象。常见的可迭代对象的一些示例有字符串、列表和字典。


生成器看起来跟函数很像,只是使用yield作为关键字而不是return。为了更好的理解,我们可以看一个例子:


def generate_numbers():

n = 0

while n < 3:

yield n

n += 1

这就是生成器函数。当被调用时,它会返回一个生成器对象:


>>>numbers = generate_numbers()

>>> type(numbers)

<class 'generator'>

需要注意的是理解状态如何封装在生成器函数的主体内。可以使用内置的next()函数来单步执行:


>>>next_number = generate_numbers()

>>> next(next_number)

>>> next(next_number)

1

>>> next(next_number)

2

如果在结尾时继续调用next()会发生什么?


StopIteration是一个内置的异常类型,一旦生成器停止执行yield语句,它将自动触发。这是for循环停止的信号。

图源:Unsplash

Yield语句


它的主要工作是以类似于return语句的方式控制生成器函数的流程。


当调用一个生成器函数或者使用生成器表达式时,会返回一个称为生成器的特殊迭代器。可以通过将此生成器分配给变量来使用它。当调用生成器上的特殊方法,例如next(),函数中的代码会执行到yield语句。


当执行到达了Python代码中的yield语句,程序就会中止函数的执行,并将产生的值返回给调用方。(相反,return会完全停止函数执行。)当一个函数被挂起时,它的状态会被保存。


在熟悉了Python的生成器之后,让我们从内存使用和代码执行花费的时间两方面来比较普通方法与使用生成器的方法。


问题陈述


假设我们必须遍历一大串数字(例如100000000),并将所有偶数的平方存储在单独的列表中。


普通方法


importmemory_profiler

import time

def check_even(numbers):

even = []

for num in numbers:

if num % 2 == 0:

even.append(num*num)

return evenif __name__ == '__main__':

m1 = memory_profiler.memory_usage()

t1 = time.clock()

cubes = check_even(range(100000000))

t2 = time.clock()

m2 = memory_profiler.memory_usage()

time_diff = t2 - t1

mem_diff = m2[0] - m1[0]

print(f"It took {time_diff} Secsand {mem_diff} Mb to execute this method")

运行后,上述代码的输出如下:


It took21.876470000000005 Secs and 1929.703125 Mb to execute this method

使用生成器


importmemory_profiler

import time

def check_even(numbers):

for num in numbers:

if num % 2 == 0:

yield num * num

if __name__ == '__main__':

m1 = memory_profiler.memory_usage()

t1 = time.clock()

cubes = check_even(range(100000000))

t2 = time.clock()

m2 = memory_profiler.memory_usage()

time_diff = t2 - t1

mem_diff = m2[0] - m1[0]

print(f"It took {time_diff} Secsand {mem_diff} Mb to execute this method")

运行后,上述代码的输出如下:


It took2.9999999995311555e-05 Secs and 0.02656277 Mb to execute this method


肉眼可见,执行时间和内存使用量都大大减少了。


生成器仅按需工作,也就是众所周知的通过惰性评估工作。这意味着它们可以节省CPU,内存和其他计算资源。

图源:Unsplash

今天,我们学习了如何使用python的生成器来减少内存使用并使代码执行更快。


这种方式的优点在于,生成器不会将所有结果都存储在内存中,而是即时生成它们,因此仅在我们请求结果时它才会使用内存。生成器还可以抽象出编写迭代器所需的许多样板代码,因此也有助于减少代码量。


快来试试吧,一定会取得让你惊喜不已的结果。


留言点赞关注

我们一起分享AI学习与发展的干货

如转载,请后台留言,遵守转载规范

标签: #python 减少内存占用