考虑以下问题:我想保留list1的属于list2的元素。所以我可以这样做:
filtered_list = [w for w in list1 if w in list2]
我需要对list1的不同示例(大约20000个不同的示例)和“常量”(冻结)list2重复相同的过程。
我怎样才能加快这个过程?
我也知道以下属性:
1)list1有重复的元素,它没有排序,它有大约10000(万)个项目。
2)list2是Python中的一个巨大的排序列表(大约200000 - 二十万个),每个元素都是唯一的。
我遇到的第一件事是,也许我可以使用一种二分搜索。但是,有没有办法在Python中执行此操作?
此外,我不介意filtered_list与list1的项目顺序相同。所以,也许我只能检查一个未重复的list1版本,并在删除list1中不属于列表2的元素后,我可以返回重复的项目。
在Python 3中有一种快速的方法吗?
将list2
转换为set
:
# do once
set2 = set(list2)
# then every time
filtered_list = [w for w in list1 if w in set2]
x in list2
是顺序的; x in set2
使用与字典相同的机制,从而实现非常快速的查找。
如果list1
没有重复项,那么将两者转换为集合并采用集合交集将是要走的路:
filtered_set = set1 & set2
但是如上所述,你会重复使用list1
。
(正如你所说,你甚至可以看到你应该删除的元素,使用set1 - set2
,但是你仍然会陷入循环以便删除 - 过滤守护者与过滤垃圾桶之间的性能应该没有任何差别,你仍然需要迭代list1
,所以没有胜过上面的方法。)
编辑回应评论:将list1
转换为Counter
将
如果你可以正常使用它(也就是你从来没有一个列表,你总是只处理一个Counter
),可能(编辑:或不;需要测试!)加快速度。但是如果你每次进行上述操作都需要将list1
预处理到counter1
,那么再次没有胜利 - 创建一个Counter
将再次涉及一个循环。