【发布时间】:2009-08-23 18:50:41
【问题描述】:
我在 Python 中有以下代码:
def point_to_index(point):
if point not in points:
points.append(point)
return points.index(point)
这段代码效率极低,尤其是因为我预计points 会增长到容纳几百万个元素。
如果点不在列表中,我遍历列表3次:
- 查找它并确定它不存在
- 转到列表末尾并添加一个新元素
- 转到列表末尾直到找到索引
如果它是在列表中,我遍历它两次: 1. 寻找它并确定它在那里 2. 几乎走到列表的末尾,直到找到索引
有没有更有效的方法来做到这一点?例如,我知道:
- 我更有可能使用不在列表中的点来调用此函数。
- 如果该点在列表中,则它更可能位于末尾而不是开头。
所以,如果我可以的话:
if point not in points:
从尾到头搜索列表,当点已经在列表中时,会提高性能。
但是,我不想这样做:
if point not in reversed(points):
因为我认为reversed(points) 本身会付出巨大的代价。
我也不想在列表的开头添加新点(假设我知道如何在 Python 中这样做),因为这会改变索引,而索引必须保持不变才能使算法起作用。
我能想到的唯一改进是,如果可能的话,从头到尾只通过一次来实现该功能。底线是:
- 有什么好的方法吗?
- 有没有更好的方法来优化功能?
编辑:我收到了一些建议,只需通过一次即可实现这一点。 index()有没有办法从头走到尾?
编辑:人们问为什么索引很重要。我正在尝试使用OFF file format 描述一个 3D 表面。此格式使用其顶点和面来描述曲面。首先列出顶点,然后使用顶点索引列表来描述面。这就是为什么一旦我将一个漩涡添加到列表中,它的索引就不能改变。
编辑:有一些建议(例如igor's)使用字典。这是扫描列表的一个很好的解决方案。但是,当我完成后,我需要按照创建的顺序打印出列表。如果我使用字典,我需要打印出按值排序的键。有什么好办法吗?
编辑:我实现了www.brool.com 的suggestion。这是最简单和最快的。它本质上是一个有序的字典,但没有开销。表演很棒!
【问题讨论】:
-
你使用列表而不是集合有什么原因吗?
-
为什么需要列表中点的索引?如果您可以一次将所有元素添加到一个集合中,您可以在 5 到 10 秒内运行此代码。
标签: python list optimization