如何查找列表是否是其他列表的子集?

时间:2016-01-04 20:16:57

标签: python

我知道如何查找列表是否是另一个列表的子集。但我想知道如何确保列表是另一个列表的有序子集。按顺序子集,我的意思是列表中的元素顺序相同

例如,如果我有以下列表

A = [1,2,3]
B = [1,2]
C = [2,1]

这里B是A的有序子集,但C不是(尽管A具有C的所有元素)

4 个答案:

答案 0 :(得分:3)

使用简单的循环按顺序遍历两个列表。最后,检查是否已经看到潜在子集列表的所有元素。

i,j = 0,0
while i < len(A) and j < len(B):
    if A[i] == B[j]:
        j += 1
    i += 1

has_as_subset = (j == len(B))

答案 1 :(得分:1)

def is_sub(sub, lst):
    ln = len(sub)
    for i in range(len(lst) - ln + 1):
        if all(sub[j] == lst[i+j] for j in range(ln)):
            return True
    return False

输出:

In [21]: A = [4, 3, 2, 1, 2, 3]

In [22]: B = [1, 2]

In [23]: C = [2, 1]

In [24]: is_sub(B, A)
Out[24]: True

In [25]: is_sub(C, A)
Out[25]: True
In [26]: B = [10,11,12,13,14,15,25]
In [27]: is_sub(B, A)
Out[27]: False
In [39]: A = [1, 2, 1, 2, 1, 2, 3]
In [40]: B = [1, 2, 3]

In [41]: is_sub(B, A)
Out[41]: True

我们不需要担心sub比lst更长,因为它停止的时间会少于start,所以我们只返回False。

您可以将它与任何:

结合使用
def is_sub(s, l):
    ln = len(s)
    return any((all(s[j] == l[i + j] for j in range(ln))
                for i in range(len(l) - ln + 1)))

根据您的使用情况,切片可能会更快:

def is_sub(sub, lst):
    ln = len(sub)
    return any(lst[i: i + ln] == sub for i in range(len(sub) - ln + 1))

如果元素可以有间隙,那么它就会简单得多,类似于kfx,你可以在一次通过或更少的时间内完成:

def is_sub_with_gap(sub, lst):
    ln, j = len(sub), 0
    for ele in lst:
        if ele == sub[j]:
            j += 1
        if j == ln:
            return True
    return False

根本区别在于你认为是一个子集:

In [6]: a,b = [1,2,3,4], [1,2,4]

In [7]: is_sub(b,a)
Out[7]: False

In [8]: is_sub_with_gap(b,a)
Out[8]: True

答案 2 :(得分:0)

a_i = 0
for b in B:
    try:
        if b == A[a_i]:
            a_i += 1
    except IndexError:
        return False
return True

基本的想法是,在耗尽A之前,你不应该耗尽B

答案 3 :(得分:0)

这是一个允许与大多数共同但不是所有其他已发布解决方案的差距(即is_sublist([1,2,4],[1,2,3,4])返回True)的版本;它还处理从父列表中的任何位置开始的子列表(同样,与大多数但不是所有其他答案一样);此外,如果子列表候选包含主列表没有的重复(即False不是[1,2,2]的子列表),则返回[1,2,3]:同样,此属性是共享的大多数但不是所有其他答案。 (据我所知,唯一能够击中所有这些目标的解决方案是kfx。)

def is_sublist( sublst, lst ):
    for element in sublst:
        try: ind = lst.index( element )
        except ValueError: return False
        lst = lst[ ind+1: ]
    return True