python游戏内存修改_Python:修改列表时的内存使用和优化

博客探讨了在处理大型数据集时,如何优化Python列表的遍历和删除操作。讨论了不同策略,如使用索引、反向遍历、创建新列表、列表推导、过滤函数以及itertools的ifilterfalse。文章指出,这些方法在时间和内存效率上有不同的权衡,特别提到了O(N^2)的复杂度问题。最后,提出了使用双向链表作为可能的高性能替代方案,但可能需要大量代码重构。
摘要由CSDN通过智能技术生成

问题

我关心的是:我将一个相对较大的数据集存储在古典的python列表中,为了处理数据,我必须遍历列表多次,对元素执行一些操作,并经常将一个项目从列表中弹出。

看来,从Python列表中删除一个项目会花费O(N),因为Python必须将元素上方的所有项目复制在一个位置。此外,由于要删除的项目数量与列表中的元素的数量成正比,这导致了O(N ^ 2)算法。

我希望找到一个具有成本效益(时间和记忆性)的解决方案。我已经研究了我可以在互联网上找到什么,并总结了我下面的不同选项。哪一个是最好的候选人?

保存本地索引:

while processingdata:

index = 0

while index < len(somelist):

item = somelist[index]

dosomestuff(item)

if somecondition(item):

del somelist[index]

else:

index += 1

这是我想出的原始解决方案。不仅这不是很优雅,但我希望有更好的方法来做到这一点,保持时间和记忆效率。

向后走列表:

while processingdata:

for i in xrange(len(somelist) - 1, -1, -1):

dosomestuff(item)

if somecondition(somelist, i):

somelist.pop(i)

这避免了增加索引变量,但是最终与原始版本的成本相同。它还打破了dosomestuff(item)的逻辑,希望以与原始列表中出现的顺序相同的顺序处理它们。

制作新的列表:

while processingdata:

for i, item in enumerate(somelist):

dosomestuff(item)

newlist = []

for item in somelist:

if somecondition(item):

newlist.append(item)

somelist = newlist

gc.collect()

这是一个非常幼稚的策略,用于从列表中删除元素,并且需要大量内存,因为必须进行几乎完整的列表。

使用列表推导:

while processingdata:

for i, item in enumerate(somelist):

dosomestuff(item)

somelist[:] = [x for x in somelist if somecondition(x)]

这是非常优雅的,但覆盖范围更多的是整个列表,并且必须复制其中的大部分元素。我的直觉是,这个操作可能比原来的del语句成本更高,至少内存明智。请记住,系统可能是巨大的,每次运行一次只能迭代一次的任何解决方案可能总是会赢。

使用过滤功能:

while processingdata:

for i, item in enumerate(somelist):

dosomestuff(item)

somelist = filter(lambda x: not subtle_condition(x), somelist)

这也创建了一个占用大量RAM的新列表。

使用itertools的过滤器函数:

from itertools import ifilterfalse

while processingdata:

for item in itertools.ifilterfalse(somecondtion, somelist):

dosomestuff(item)

此版本的过滤器调用不会创建新列表,但不会在破坏算法逻辑的每个项目上调用dosomestuff。我仅仅是为了创建一个详尽的列表来包括这个例子。

在行走时将物品移动到列表中

while processingdata:

index = 0

for item in somelist:

dosomestuff(item)

if not somecondition(item):

somelist[index] = item

index += 1

del somelist[index:]

这是一种似乎具有成本效益的微妙方法。我认为它将移动每个项目(或每个项目的指针?)一次导致O(N)算法。最后,我希望Python将足够智能,最终调整列表的大小,而无需为列表的新副本分配内存。不确定。

放弃Python列表:

class Doubly_Linked_List:

def __init__(self):

self.first = None

self.last = None

self.n = 0

def __len__(self):

return self.n

def __iter__(self):

return DLLIter(self)

def iterator(self):

return self.__iter__()

def append(self, x):

x = DLLElement(x)

x.next = None

if self.last is None:

x.prev = None

self.last = x

self.first = x

self.n = 1

else:

x.prev = self.last

x.prev.next = x

self.last = x

self.n += 1

class DLLElement:

def __init__(self, x):

self.next = None

self.data = x

self.prev = None

class DLLIter:

etc...

这种类型的对象类似于python列表,有限的方式。然而,删除元素是保证O(1)。我不想去这里,因为这将需要大量的代码重构几乎无处不在。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值