list1
包含大约50,000个长度的索引列表。
list2
包含一个列表或单词的长度大约为60,000。
我使用以下列表理解来遍历列表:
newList= [w for w in list2 if list2.index(w) in list1]
问题在于运行此程序需要花费相当长的时间,是否有人知道有任何提示提示或技巧来加快此过程,或者以更快的方式实现相同的结果。
我发现将list1设置为set可以加快该过程,但仍然比我想要的慢
答案 0 :(得分:1)
大多数列表操作为O(n)。您的清单理解单线可能为O(n ^ 3)。因此,考虑到这一点,我建议将其分为两行,而不是一行:
indices = set(x for x in list1 if x < len(list2))
newList = [w for i,w in enumerate(list2) if i in indices]
第一行从list1
中提取所有可能包含在list2
中的索引。这对应于您的条款list2.index(w) in list1
。第二行是选择list2
中包含在索引集中的那些行。使用设置操作可以将搜索时间从O(n)减少到O(1)。使用枚举可以避免list2.index()
调用,该调用还将O(n)减少为O(1)。这两行仅在O(n)时间运行。
如果您的list2
包含重复项,则需要对此进行更改。但仍然可能是O(n):
indices = set(x for x in list1 if x < len(list2))
lookup = {}
for i,w in enumerate(list2):
if w not in lookup:
lookup[w] = i
newList = [w for w in list2 if lookup[w] in indices]
答案 1 :(得分:0)
index()
需要在列表中进行搜索以找到项目的索引,并且仅找到找到的第一个项目的第一个索引(如果有重复项,则很重要)。这意味着这是O(n² )
算法。然后,在整个list1中搜索它,使其成为O(n² + mn)
。但是您已经知道索引了,因为您正在遍历list2
-没有理由搜索它。因此,不必再次搜索,只需将索引设置为集合,然后查看您所在的索引是否在其中。这将是O(n)。
list2 = ['hello', 'dog', 'cat', 'house']
list1 = set([0, 2, 3])
[w for i, w in enumerate(list2) if i in list1]
#['hello', 'cat', 'house']