问题描述
我有两个列表,
l1 = [1,4,3,2,5]
l2 = [4,10]
list(set(l1).intersection(set(l2)))
>> [2,4]
但是它改变了l1
的顺序,我不想改变顺序所以结果应该是,
>> [4,2]
正在寻找不改变顺序的最快方法?
解决方法
您可以使用 l1
对结果重新排序:
>>> sorted(set(l1).intersection(set(l2)),key=l1.index)
[4,3,2]
您也可以使用列表理解而不是集合交集,但我相信第一种方法通常会更快,具体取决于每个列表中的元素数量,因为搜索列表是 O(n)
和下面的解决方案变成O(n*m)
:
>>> [i for i in l1 if i in l2]
[4,2]
最后可以通过将l2
转化为集合来优化理解方法:
>>> s2 = set(l2)
>>> [i for i in l1 if i in s2]
[4,2]
,
假设您想保留 l1
的序列。如果 x
存在于 l1
中,则时间复杂度为 O(n^2) 的算法将是为 x
中的每个项目 l2
找到。以下代码可以工作
common_elements = [x for x in l1 if x in l2]
您可以使用 map(dict) 将时间复杂度降低到 O(n)
lookup_map = {x: True for x in l2}
common_elements = [x for x in l1 if x in lookup_map]
编辑:发现 Python 的 set
是作为哈希映射实现的,并且在平均情况下,查找需要 O(1) https://wiki.python.org/moin/TimeComplexity,因此以下也应该有一个平均值。 O(n) 的案例复杂度
common_elements = [x for x in l1 if x in set(l2)]
,
最快的方法取决于数据,但这个解决方案应该是最快的方法之一
[x for x in [1,4,2,5] if x in {4,10}]