【问题标题】:Seeing if a list exists within another list?查看一个列表是否存在于另一个列表中?
【发布时间】:2010-02-21 11:39:33
【问题描述】:

基本上可以说我有:

>>> a = [1,3,2,2,2]
>>> b = [1,3,2]

我想看看 b 中的所有元素是否存在于 a 中,并且顺序相同。所以对于上面的例子,b 将存在于 a 中。

我有点希望有一个非常简单的单行答案。

【问题讨论】:

  • 到目前为止你尝试过什么?这听起来像是家庭作业,所以最好展示一下你所做的事情。
  • 你的意思是:“我想看看b中的所有元素是否连续存在于a中”。 “以相同的顺序”是一个较弱的陈述。
  • 对不起,我尝试了很长的路要走,只是通过 a,检查第一个元素是否正确,然后继续,如果下一个等于第二个继续,否则重新开始。编写这个大循环似乎很乏味和草率。但是我会经常使用这个。这适用于与某个订购系统/交付使用的运行长度编码相关的工作项目。基本上,我们真正可以交互并拥有自定义功能的唯一方法是直接使用工单,这是一个糟糕的 80 年代代码 cthulu。
  • 那么它们必须是连续的('substring')还是不连续的('subsequence')?

标签: python list


【解决方案1】:

这是一个简单的 O(n * m) 算法:

any(a[i:i + len(b)] == b for i in range(len(a) - len(b) + 1))

请注意,这不是最快的方法。如果您需要高性能,您可以使用与string searching algorithms 中使用的技术类似的技术。

【讨论】:

  • 完美,这正是我想要的。
【解决方案2】:

如果你所说的“以相同的顺序”是指子序列(而不是子字符串),那么这个非单行应该可以快速工作:

  def is_subsequence(x, y):
    i, j = 0, 0
    while i < len(x) and j < len(y):
      if x[i] == y[j]:
        i += 1
      j += 1
    return i == len(x)

【讨论】:

  • 如果你想让你的代码自我注释,你真的应该把xy重命名为更具描述性的名字;否则,记录您的代码并解释哪个是哪个。是is_subsequence("abcecde", "cde") 还是is_subsequence("cde", "abcecde")
【解决方案3】:

这是一个适用于整数列表的解决方案。

例如将 [1, 3, 2] 变成字符串“'1', '3', '2'”。然后使用内置的字符串包含来查看它是否在另一个列表中。

repr(map(str, b))[1:-1] in repr(map(str, a))[1:-1]

【讨论】:

    【解决方案4】:

    这可能不是很有效,但您可以使用:

    In [1]: a = [1,3,2,2,2]
    
    In [2]: b = [1,3,2]
    
    In [3]: b == [val for val in a if val in b]
    Out[3]: False
    
    In [4]: a = [6,1,3,2,5,4]
    
    In [5]: b == [val for val in a if val in b]
    Out[5]: True
    

    第一个测试返回 False,因为 2 重复。问题是您一般如何处理重复项。如果您只想在最后切断它们,那么您可以将列表修剪到 a 的长度:

    In [6]: a = [1,3,2,2,2]
    
    In [7]: b == [val for val in a if val in b][:len(b)]
    Out[7]: True
    

    【讨论】:

      【解决方案5】:

      抱歉,您想要做的实际上与字符串匹配相同(尽管使用列表而不是字符串)。您可能想查看 Knuth-Morris-PrattBoyer Moore 以了解线性时间算法。

      编辑:
      我假设“按顺序”是指序列中连续的任何位置。如果它们之间可以被其他元素分开,那么这不是您想要的解决方案。

      【讨论】:

        【解决方案6】:

        如果它“以相同的顺序”,

        >>> a = [1,3,2,2,2]
        >>> b = [1,3,2]
        >>> ' '.join(map(str,b)) in ' '.join(map(str,a))
        True
        
        >>> a = [1,1,2,2,2,13,2]
        >>> b = [1,3,2]
        >>> ' '.join(map(str,b)) in ' '.join(map(str,a))
        False
        

        【讨论】:

        • 这也为b = [13, 2]返回True。 (列表中元素的字符串表示形式不要求全部为一个字符)。
        • 然后我们加入一个空格并且不会为空。那应该可以解决它。
        • 抱歉,这并不能解决问题。这现在将为a = ['1', '2']b = ['1 2'] 返回True。 (问题中也没有要求元素是数字)。
        • 也没有要求元素不是数字。
        • 要求只是它们是列表,并且您的方法在很多情况下都不起作用。如果您在答案中添加一个仅适用于数字的附带条件,那很好。否则,您可能会争辩说,除了明确说明的数字之外,没有任何要求,在这种情况下,最好的答案就是 True
        猜你喜欢
        • 1970-01-01
        • 2023-02-22
        • 1970-01-01
        • 2021-02-11
        • 1970-01-01
        • 2022-01-06
        • 1970-01-01
        • 2017-04-18
        • 2013-12-12
        相关资源
        最近更新 更多