【问题标题】:finding item in two lists efficiently Python有效地在两个列表中查找项目 Python
【发布时间】:2016-02-16 18:42:21
【问题描述】:

我有一个工作函数,允许我搜索两个列表并查看 list1 中的项目是否存在于 list2 中,如果某个项目不存在于 list1 中的 list2 中,那么我希望该输出到另一个列表。然而,这需要 AGES 才能运行,我想知道是否有更快的方法来做到这一点。

def compare(list1,list2):
    x=[]
    for i in list1:
        if i not in list2:
            x.append(i)

    return x

【问题讨论】:

  • 重申目标以确保我清楚:此函数的最终结果是一个列表,其中仅包含list1 中未出现在list2 中的元素?
  • 如果是这样,[x for x in list1 if x not in list2] 似乎是一个相当快速和直接的替代方案。
  • 是的,比我现在更快的方式
  • 那不等于我已经拥有的吗?
  • 您需要保留订单吗?如果没有,list(set(list1) - set(list2))

标签: python


【解决方案1】:

由于您只检查是否包含在 list2 中,因此将其设置为一组:

def compare(list1, list2):
    s2 = set(list2)
    result = [i  for i in list1  if i not in s2] # simple list comprehension
    return result

这保留了程序的输入顺序和语义,同时显着加快了速度:设置包含测试是 O(1),而列表包含测试是 O(n),将整个算法从 O(n^2) 降低为 O(n)。

【讨论】:

    【解决方案2】:

    你可以使用集合。

    例子:

    >>> list1 = ['a', 'b', 'c']
    >>> list2 = ['c', 'd', 'e']
    >>> set(list1) - set(list2)
    {'b', 'a'}
    

    默认情况下,集合不保留顺序。如果订单对您很重要,请查看OrderedSet 的配方。

    【讨论】:

    • 顺序不重要谢谢你我想接受你的两个答案,但很遗憾不能
    【解决方案3】:

    你可以使用集合吗?

    应该是这样的:

    print list(set(list1)-set(list2))

    但它会删除重复项。

    【讨论】:

    • 删除重复项会很棒
    • 我们确定这比列表理解更快吗? set 必须消耗整个列表才能添加它们,对吗?然后你在最后转换回一个列表(没有原始排序)。我想查看一些timeit 的结果。
    • 我会看看不同的结果并编辑我的答案
    • @Two-BitAlchemist 对于大型列表,它肯定会快得多。集合算法运行时间为 O(n1 + n2)(散列 n1 和 n2 的每个成员的成本),但列表推导运行时间将是 O(n1 * n2)(在 n2 中找到 n1 的每个成员的成本,其中最坏的情况是 n1 不在 n2 中。)
    • 有没有办法使用集合来保存重复项? (只是出于好奇)
    【解决方案4】:

    如果您不介意丢失订单和重复,set1 - set2 的答案是正确的。但是即使您这样做,如果list2 很大,使用集合也可以极大地提高程序的效率和可读性:

    set2 = set(list2)
    result = [item for item in list1 if item not in set2]
    

    生成集合的成本是O(len(list2))。所以这种方法的运行时间是O(len(list2) + len(list1)),除非 list2 非常小,否则很有意义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-10
      • 1970-01-01
      • 2017-01-31
      • 2013-02-28
      • 2021-09-09
      • 2011-03-03
      • 2021-12-24
      • 1970-01-01
      相关资源
      最近更新 更多