所以我有85个项目的清单。我想不断减少这个列表的一半(基本上是对项目的二进制搜索) - 我的问题是,减少列表的最有效方法是什么?列表理解将不断创建列表的副本,这是不理想的。我希望就地删除我的列表范围,直到我留下一个元素。
我不确定这是否相关,但我使用collections.deque而不是标准列表。他们可能或多或少地以相同的方式工作,所以我怀疑这很重要。
答案 0 :(得分:3)
仅仅85件,说实话,你想要使用的几乎所有方法都足够快。不要过早优化。
也就是说,根据您实际执行的操作,list
可能比deque
更快。 deque
在两端添加和删除项目的速度更快,但不支持切片。
使用列表,如果要复制或删除连续范围的项目(例如,前42个),可以使用切片执行此操作。假设每次传递消除了一半列表,将项目复制到新列表平均比从现有列表中删除项目要慢(删除需要将未被删除的列表的一半移到内存中“向左”,这将是大约与复制另一半相同的时间成本,但你并不总是需要这样做;删除列表的后半部分不需要移动任何东西)。
要有效地使用deque
执行此操作,您可能希望pop()
或popleft()
项目而不是切片项目(许多属性访问和方法调用,这些都是相对昂贵的Python),你必须编写控制Python操作的循环,这将比原生切片操作慢。
由于你说它基本上是一个二进制搜索,实际上最简单的方法就是在不修改原始容器的情况下简单地找到你要保留的项目,然后返回一个容纳该单个项目的新容器。 list
比deque
更快,因为您将通过索引进行大量访问项目。要在deque
中执行此操作,每次访问项目时都要求Python从头开始关注链接列表,而按索引访问项目则是list
的简单快速计算。
答案 1 :(得分:1)
collections.deque
是通过链表实现的,因此二进制搜索比线性搜索慢多。重新思考你的方法。
答案 2 :(得分:1)
不确定这是你真正需要的,但是:
x = range(100)
while len(x) > 1:
if condition:
x = x[:int(len(x)/2)]
else:
x = x[int(len(x)/2):]
答案 3 :(得分:1)
答案 4 :(得分:0)
在上一个问题中,我比较了许多用于删除给定谓词的项目列表的技术。 (也就是说,我有一个函数,对于是否保留特定项目,返回True或False。)我记得使用列表理解是最快的。事实是,复制真的很便宜。
您可以做的唯一提高速度的方法取决于您要删除的项目。但是你没有说明任何事情,所以我不能提出任何建议。