【问题标题】:What is the best way to test a list contain another list (w/o gap) in python?在 python 中测试一个列表是否包含另一个列表(无间隙)的最佳方法是什么?
【发布时间】:2014-01-19 13:54:14
【问题描述】:

假设我有一个列表x=[1, 2, 3, 4],它包含子列表[1][2][3][4][1, 2][2, 3][3, 4][1,2,3]、@ 987654330@ 和[1,2,3,4]。但它不包含 [1, 3] 之类的内容,因为 2 在 x 中的 1 和 3 之间出现了一个间隙。

有谁知道最好的方法是测试一个列表是否包含在另一个列表中而没有间隙?我曾想过一个 for-loop 解决方案,但它可能不是一个很好的解决方案。谢谢。

【问题讨论】:

  • 您尝试了吗???,您可以尝试使用字符串的所有可能子字符串,例如在 '1234' 中,子字符串 '13' 是不可能的
  • 为什么要签入其他列表?检查要检查的列表,所有元素是否连续还不够吗?

标签: python list subsequence


【解决方案1】:

你的问题是:

有谁知道测试列表是否包含的最佳方法是什么 在另一个列表中没有间隙?

这实际上与在另一个字符串中查找字符串的问题相同。为此,您可以使用大量算法。

Rabin-Karp、Boyer-Moore、Knuth-Morris 等。我喜欢 Boyer-Moore,因为它简单。在互联网上查看详细信息。当然你也可以检查你的列表是否从任何可能的位置开始,但是复杂度不是最优的(你可以在这里找到这样的解决方案:Check for presence of a sliced list in Python)。

这里有一个快速(和简化)的实现:

def boyer(x, sublist):
    p = len(sublist) - 1
    i = 0
    while i + p < len(x):
        if x[i + p] == sublist[p]:
            if p == 0:
                return True
            p -= 1
        elif x[i + p] in sublist:
            i += 1
            p = len(sublist) - 1
        else:
            i = i + p + 1
            p = len(sublist) - 1
    return False

请注意,此代码应经过仔细测试,更多的是展示暴力方法的替代方法。 x[i + p] in sublist 的时间复杂度是线性的,应该以不同的方式实现以获得 O(1) 方法。目前,正因为如此,它不会比蛮力方法更好。

【讨论】:

    【解决方案2】:

    你可以试试

    ' '.join(str(c) for c in list1) in ' '.join(str(c) for c in list2)
    

    【讨论】:

      【解决方案3】:
      sequences = [
          [1], [2],
          [1, 2], [2, 3], [3, 6],
          [1, 2, 3], [2, 3, 4], [1, 2, 3, 5],
      ]
      
      bad_seq = lambda s: s and s != list(range(s[0], s[0] + len(s)))
      print filter(bad_seq, sequences)   # [[3, 6], [1, 2, 3, 5]]
      

      【讨论】:

        【解决方案4】:

        只是另一种解决方案,不确定最好的解决方案,如果我不清楚您的问题,请告诉我。

        ls = [[1], [2], [3], [4], [1, 2], [2, 3], [3, 6], [1, 2, 3], [2, 3, 4], [1, 2, 3, 5]]
        
        def gap(l):
            for ls in l:
                result = list(set(map(lambda x: x[1] - x[0], zip(ls[0:], ls[1:]) )))
                if result and (len(result) > 1 or result[0] > 1):
                    print ls
        gap(ls)
        

        输出: [3,6] [1、2、3、5]

        【讨论】:

          【解决方案5】:

          您可以对主列表中子列表的索引使用 numpy-diff 函数

          In [427]: x=[1, 2, 3, 4]
          
          In [428]: y = [1,3]
          
          In [429]: z = [1,2,3]
          
          In [430]: w = [2,1]
          
          In [431]: import numpy as np
          
          In [432]: sub_indices = [x.index(x1) for x1 in y]
          

          现在,sub_indices 应该如下所示:[0, 2] 所以你可以检查索引之间的差异:

          In [433]: np.all(np.diff(sub_indices) == 1)
          Out[433]: False
          
          In [434]: sub_indices = [x.index(x1) for x1 in z]
          
          In [435]: np.all(np.diff(sub_indices) == 1)
          Out[435]: True
          
          In [436]: sub_indices = [x.index(x1) for x1 in w]
          
          In [437]: np.all(np.diff(sub_indices) == 1)
          Out[437]: False
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-05-15
            • 2011-04-20
            • 2015-10-29
            相关资源
            最近更新 更多