Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find if a list is a subset of another list in order? [closed]

Tags:

python

I know how to find whether a list is a subset of another list. But I was wondering how do you make sure that a list is an ordered subset of another list. By ordered subset I mean that the elements in both the list are in same order

For example if I have the following lists

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

Here B is an ordered subset of A but C is not (although A has all elements of C)

like image 790
brokendreams Avatar asked Jan 04 '16 20:01

brokendreams


People also ask

How do you check if list is a subset of another list?

issubset() function. The most used and recommended method to check for a sublist. This function is tailor made to perform the particular task of checking if one list is a subset of another.

How do you determine if a list is a subset of another list Python?

issubset() to check if a list is a subset of another list. Use set(list) to convert the lists to sets . Call set1. issubset(set2) to return a Boolean indicating whether set1 is a subset of set2 .

How do you check if a list is a subset of another list C#?

You can simply check to see that the set difference between query2 and query1 is the empty set: var isSubset = ! query2. Except(query1).


2 Answers

Use a simple loop to iterate through both lists in order. At the end, check if all elements of the potential subset list have been seen.

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))
like image 169
kfx Avatar answered Oct 29 '22 06:10

kfx


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

Output:

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

We don't need to worry about the sub being longer than lst as is it is stop will be less that start so we just return False.

You can combine it with any:

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

Depending on your use case slicing might be faster:

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

If the elements can have gaps then it is a lot simpler, similar to kfx's you can do it in a single pass or less:

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

The fundamental difference being what you consider a subset:

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
like image 45
Padraic Cunningham Avatar answered Oct 29 '22 05:10

Padraic Cunningham