Python:使用列表推导式过滤列表的更快方法
Python: Faster way to filter a list using list comprehension
考虑以下问题:我想保留 list1 中属于 list2 的元素。所以我可以这样做:
filtered_list = [w for w in list1 if w in list2]
我需要对 list1 的不同示例(大约 20000 个不同的示例)和 "constant"(冻结的)list2 重复相同的过程。
我怎样才能加快这个过程?
我还知道以下属性:
1) list1 有重复元素且未排序且大约有 10000(万)项。
2) list2 是一个巨大的排序列表(大约 200000 - 20 万)条目 Python) 并且每个元素都是唯一的。
我想到的第一件事是也许我可以使用一种二进制搜索。但是,在 Python 中有没有办法做到这一点?
此外,如果 filtered_list 的 list1 项目顺序相同,我不介意。所以,也许我可以只检查 list1 的未重复版本,并且在删除 list1 中不属于列表 2 的元素后,我可以 return 重复的项目。
在 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
看到您应该删除的元素,但是您仍然会陷入循环以删除 - 应该没有任何区别在过滤 keepers 和过滤垃圾之间的性能上,你仍然需要迭代 list1
,所以这并不能胜过上面的方法。)
编辑以回应评论:将 list1
转换为 Counter
会 可能(编辑:或不;需要测试!)加快速度 如果你能像那样正常使用它(即你从来没有列表,你总是只处理一个Counter
)。但是,如果您每次执行上述操作时都必须将 list1
预处理为 counter1
,那么这同样是失败的 - 创建一个 Counter
将再次涉及一个循环。
考虑以下问题:我想保留 list1 中属于 list2 的元素。所以我可以这样做:
filtered_list = [w for w in list1 if w in list2]
我需要对 list1 的不同示例(大约 20000 个不同的示例)和 "constant"(冻结的)list2 重复相同的过程。
我怎样才能加快这个过程?
我还知道以下属性:
1) list1 有重复元素且未排序且大约有 10000(万)项。
2) list2 是一个巨大的排序列表(大约 200000 - 20 万)条目 Python) 并且每个元素都是唯一的。
我想到的第一件事是也许我可以使用一种二进制搜索。但是,在 Python 中有没有办法做到这一点?
此外,如果 filtered_list 的 list1 项目顺序相同,我不介意。所以,也许我可以只检查 list1 的未重复版本,并且在删除 list1 中不属于列表 2 的元素后,我可以 return 重复的项目。
在 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
看到您应该删除的元素,但是您仍然会陷入循环以删除 - 应该没有任何区别在过滤 keepers 和过滤垃圾之间的性能上,你仍然需要迭代 list1
,所以这并不能胜过上面的方法。)
编辑以回应评论:将 list1
转换为 Counter
会 可能(编辑:或不;需要测试!)加快速度 如果你能像那样正常使用它(即你从来没有列表,你总是只处理一个Counter
)。但是,如果您每次执行上述操作时都必须将 list1
预处理为 counter1
,那么这同样是失败的 - 创建一个 Counter
将再次涉及一个循环。