我有大约50万个项目需要放在一个列表中,我不能有重复的东西,如果一个项目已经存在,我需要获取它的索引。到目前为止,我已经
if Item in List:
ItemNumber=List.index(Item)
else:
List.append(Item)
ItemNumber=List.index(Item)问题是,随着列表的增长,它会变得越来越慢,直到某个时候,它就不值得去做了。我只能使用python2.5,因为它是一个嵌入式系统。
发布于 2011-09-21 01:32:19
您可以使用set (从2.4版开始的CPython中)高效地查找重复值。如果你真的需要一个索引系统,你可以同时使用set和list。
使用集合进行查找将消除if Item in List的开销,但不会消除List.index(Item)的开销
请注意,在List.append(Item)之后,ItemNumber=List.index(Item)将是非常低效的。您知道列表的长度,因此可以使用ItemNumber = len(List)-1检索索引。
要完全消除List.index的开销(因为该方法将在列表中搜索-在较大的集合上效率非常低),您可以使用字典将项目映射回它们的索引。
我可能会重写如下:
# earlier in the program, NOT inside the loop
Dup = {}
# inside your loop to add items:
if Item in Dup:
ItemNumber = Dup[Item]
else:
List.append(Item)
Dup[Item] = ItemNumber = len(List)-1发布于 2011-09-21 01:32:20
如果您确实需要将数据保存在数组中,我会使用单独的字典来跟踪重复项。这需要两倍的内存,但不会显著减慢。
existing = dict()
if Item in existing:
ItemNumber = existing[Item]
else:
ItemNumber = existing[Item] = len(List)
List.append(Item)但是,如果您不需要保存项目的顺序,则应该使用set。它占用的空间几乎和列表一样小,但速度却和字典一样快。
Items = set()
# ...
Items.add(Item) # will do nothing if Item is already added这两种方法都要求您的对象是可哈希的。在Python中,大多数类型都是hashable的,除非它们是内容可以修改的容器。例如:lists是不可哈希的,因为您可以修改它们的内容,但tuples是可哈希的,因为您不能。
如果您试图存储不可哈希的值,则没有快速的通用解决方案。
发布于 2011-09-21 01:32:41
您可以对检查进行很多改进:
check = set(List)
for Item in NewList:
if Item in check: ItemNumber = List.index(Item)
else:
ItemNumber = len(List)
List.append(Item)或者,更好的是,如果顺序不重要,您可以这样做:
oldlist = set(List)
addlist = set(AddList)
newlist = list(oldlist | addlist)如果您需要循环遍历复制的项:
for item in (oldlist & addlist):
pass # do stuffhttps://stackoverflow.com/questions/7489219
复制相似问题