Python:使用列表推导过滤列表的更快方法

问题描述 投票:0回答:1

考虑以下问题:我想保留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中有一种快速的方法吗?

python-3.x list-comprehension binary-search
1个回答
2
投票

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将再次涉及一个循环。

© www.soinside.com 2019 - 2024. All rights reserved.