Python 3.x Python:使用列表理解过滤列表的更快方法

Python 3.x Python:使用列表理解过滤列表的更快方法,python-3.x,list-comprehension,binary-search,Python 3.x,List Comprehension,Binary Search,考虑以下问题:我想保留属于list2的list1元素。所以我可以这样做: filtered_list = [w for w in list1 if w in list2] 我需要对列表1的不同示例(大约20000个不同示例)和“常量”(冻结)列表2重复相同的过程 如何加快流程? 我还知道以下属性: 1) 列表1有重复的元素,没有排序,大约有10000(万)个项目 2) list2是一个巨大的排序列表(Python中大约200000-200000个条目),每个元素都是唯一的 我想到的第一件事是,

考虑以下问题:我想保留属于list2的list1元素。所以我可以这样做:

filtered_list = [w for w in list1 if w in list2]
我需要对列表1的不同示例(大约20000个不同示例)和“常量”(冻结)列表2重复相同的过程

如何加快流程?

我还知道以下属性:

1) 列表1有重复的元素,没有排序,大约有10000(万)个项目

2) list2是一个巨大的排序列表(Python中大约200000-200000个条目),每个元素都是唯一的

我想到的第一件事是,也许我可以使用一种二进制搜索。然而,在Python中有没有一种方法可以做到这一点

此外,我不介意过滤后的列表是否具有与列表1相同的项目顺序。因此,也许我只能检查列表1的未重复版本,在删除列表1中不属于列表2的元素后,我可以返回重复的项


在Python3中有没有一种快速的方法可以做到这一点?

list2
转换为
set

# do once
set2 = set(list2)

# then every time
filtered_list = [w for w in list1 if w in set2]
列表2中的x是顺序的x使用了与字典相同的机制,从而实现了非常快速的查找

如果
list1
没有重复项,则将两者转换为集合并进行集合相交将是一种方法:

filtered_set = set1 & set2
但是对于重复项,您必须像上面那样迭代
list1

(正如您所说,您甚至可以使用
set1-set2
看到您应该删除的元素,但是为了删除这些元素,您仍然会陷入一个循环中-过滤守护者和过滤垃圾之间的性能不应该有任何区别,您仍然必须迭代
list1
,因此这并不能战胜上述方法。)


根据注释进行编辑:将
列表1
转换为
计数器可能(编辑:或不编辑;需要测试!)会加快速度,如果您可以像那样正常使用它(即,您从来没有列表,您总是只处理
计数器
)。但是,如果每次执行上述操作时都必须将
list1
预处理为
counter1
,这同样不是双赢的-创建
计数器将再次涉及循环。

list2
转换为
集合

# do once
set2 = set(list2)

# then every time
filtered_list = [w for w in list1 if w in set2]
列表2中的
x是顺序的x使用了与字典相同的机制,从而实现了非常快速的查找

如果
list1
没有重复项,则将两者转换为集合并进行集合相交将是一种方法:

filtered_set = set1 & set2
但是对于重复项,您必须像上面那样迭代
list1

(正如您所说,您甚至可以使用
set1-set2
看到您应该删除的元素,但是为了删除这些元素,您仍然会陷入一个循环中-过滤守护者和过滤垃圾之间的性能不应该有任何区别,您仍然必须迭代
list1
,因此这并不能战胜上述方法。)


根据注释进行编辑:将
列表1
转换为
计数器可能(编辑:或不编辑;需要测试!)会加快速度,如果您可以像那样正常使用它(即,您从来没有列表,您总是只处理
计数器
)。但是,如果每次执行上述操作时都必须将
list1
预处理为
counter1
,这同样不是双赢的-创建
计数器将再次涉及一个循环。

如果set2是一个冻结集或它无关紧要,我会改进该过程?我是否可以将每个列表1转换为一本字典,其中每个单词都有该单词出现的次数?但是,我会花额外的时间来处理这个过程。这有什么意义吗?请参阅上面关于“一本字典,其中每个单词都有该单词出现的次数”(实际上是
collections.Counter
)。请参阅关于
frozenset
。如果set2是一个冻结集,或者它不重要,我会改进这个过程?我是否可以将每个列表1转换为一本字典,其中每个单词都有该单词出现的次数?但是,我会花额外的时间来处理这个过程。这有什么意义吗?请参阅上面关于“一本字典,其中每个单词都有该单词出现的次数”(实际上是
collections.Counter
)。请参阅关于
frozenset
。元素是字符串还是字节序列?在这种情况下,这似乎非常适合。你可以试试看。添加一些示例代码,让我最终给出答案。@Sigismondo怀疑。。。阿霍·科拉西克(Aho Corasick)在查找子字符串(或者更一般地说是子序列)方面非常出色,但对列表交叉点却无能为力。。。事实上是的,我认为列表1是某种文本。如果list1元素是独立的,那么您是绝对正确的@Sigismondo都是字符串列表。我不知道这是否是另一种解决方案。它与正则表达式类似,只是寻找子字符串。替换是每种实现语言添加的东西,并与人们心目中的regex联系在一起;但无论是正则表达式还是aho-corasick都不会这样做,它们只是告诉你东西在哪里。元素是字符串还是字节序列?在这种情况下,这似乎非常适合。你可以试试看。添加一些示例代码,让我最终给出答案。@Sigismondo怀疑。。。阿霍·科拉西克(Aho Corasick)在查找子字符串(或者更一般地说是子序列)方面非常出色,但对列表交叉点却无能为力。。。事实上是的,我认为列表1是某种文本。如果list1元素是独立的,那么您是绝对正确的@Sigismondo都是字符串列表。我不知道这是否是另一种解决方案。它与正则表达式类似,只是寻找子字符串。替换是每种实现语言添加的东西,并与人们心目中的regex联系在一起;B