python 链表操作 优化_Python:如何修改列表时内存的使用和优化?

问题

我的关注点如下:我将一个相对性较大的数据集存储在一个经典的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)

这避免了增加索引变量,但最终的代价与原始版本相同。

列一个新的清单: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)]

这是非常优雅的,但在掩盖之下,它再一次遍历整个列表,并且必须复制其中的大多数元素。

使用过滤器功能: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)

此版本的筛选器调用不会创建新列表,但不会对每一项调用doomestuff,从而破坏算法的逻辑。我列入这个例子只是为了创建一个详尽的清单。

边走边移动列表上的项目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)。 我不想去这里,因为这需要大量的代码重构几乎无处不在。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值