【问题标题】:fastest way find the common elements of two lists without changing the sequence of first list最快的方法找到两个列表的共同元素而不改变第一个列表的顺序
【发布时间】:2021-07-16 08:29:22
【问题描述】:

我有两个列表,

 l1 = [1,4,3,2,5]
 l2 = [4,3,2,10]

现在我想找到列表之间的共同元素,所以我使用以下代码,

list(set(l1).intersection(set(l2)))
>> [2, 3, 4]

但是它改变了l1的序列,我不想改变序列所以结果应该是,

>> [4, 3, 2]

寻找在不改变顺序的情况下最快的方法?

【问题讨论】:

标签: python python-3.x list dictionary list-comprehension


【解决方案1】:

您可以使用l1 重新排序结果:

>>> sorted(set(l1).intersection(set(l2)), key=l1.index)
[4, 3, 2]

您也可以使用列表推导而不是集合交集,但我相信第一种方法通常会更快,具体取决于每个列表中的元素数量,因为搜索列表是 O(n) 而下面的解决方案变成 @ 987654324@:

>>> [i for i in l1 if i in l2]
[4, 3, 2]

最后,您可以通过将l2 转换为集合来优化理解方法:

>>> s2 = set(l2)
>>> [i for i in l1 if i in s2]
[4, 3, 2]

【讨论】:

  • 只是添加一些分析——将 l2 转换为一个集合并对照它检查 l1 是有效的解决方案,应该使用。如果它们出现在 l1 中,它还会维护相同值的多个副本,维护顺序,并且做最少的工作。对于较大的输入,此处介绍的其他解决方案明显较慢。
【解决方案2】:

假设您想保留l1 的序列。如果x 存在于l2 中,则O(n^2) 时间复杂度的算法将找到l1 中的每个项目x。以下代码将起作用

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)]

【讨论】:

    【解决方案3】:

    最快的方法取决于数据,但这个解决方案应该是最快的方法之一

    [x for x in [1, 4, 3, 2, 5] if x in {4, 3, 2, 10}]
    

    【讨论】:

      猜你喜欢
      • 2013-05-14
      • 1970-01-01
      • 1970-01-01
      • 2021-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-22
      • 1970-01-01
      • 2019-12-21
      相关资源
      最近更新 更多