20

I have these two arrays:

A = [1,2,3,4,5,6,7,8,9,0] 

And:

B = [4,5,6,7]

Is there a way to check if B is a sublist in A with the same exact order of items?

5
  • 2
    list order is to be preserved, right? Commented Dec 26, 2013 at 18:32
  • The order of the elements of B is the same as the part that includes it in A, if is that your question. Commented Dec 26, 2013 at 18:34
  • I believe he's asking does it matter what order the elements are in? For example... Would B=[4,6,5,7] be just as good, or does order matter? Commented Dec 26, 2013 at 18:36
  • 2
    The order of the elements in A and B matters. Is like see if B is a cut of the list A. Commented Dec 26, 2013 at 18:42
  • Any ideas if I wanna get the rest array, like C = A - B = [1,2,3,8,9,0]? Commented May 19, 2021 at 6:59

8 Answers 8

61

issubset should help you

set(B).issubset(set(A))

e.g.:

>>> A= [1,2,3,4]
>>> B= [2,3]
>>> set(B).issubset(set(A))
True

edit: wrong, this solution does not imply the order of the elements!

Sign up to request clarification or add additional context in comments.

2 Comments

+1 as I found this helpful and also appreciate the note on how it didn't quite answer the OP but was left here for those who might stumble upon it. Thanks.
also note that set([]).issubset(set([1,2,3])) evaluates to True
10

How about this:

A = [1,2,3,4,5,6,7,8,9,0] 

B = [4,5,6,7]
C = [7,8,9,0]
D = [4,6,7,5]

def is_slice_in_list(s,l):
    len_s = len(s) #so we don't recompute length of s on every iteration
    return any(s == l[i:len_s+i] for i in xrange(len(l) - len_s+1))

Result:

>>> is_slice_in_list(B,A)
True
>>> is_slice_in_list(C,A)
True
>>> is_slice_in_list(D,A)
False

Comments

4

Using slicing:

for i in range(len(A) - len(B)):
    if A[i:i+len(B)] == B:
        return True
return False

Something like that will work if your A is larger than B.

1 Comment

That would work even if A is smaller than B, the only case you should care of is equal lengths. That note shows that you probably should use range(len(A)-len(B)+1) instead.
2

I prefer to use index to identify the starting point. With this small example, it is faster than the iterative solutions:

def foo(A,B):
    n=-1
    while True:
        try:
            n = A.index(B[0],n+1)
        except ValueError:
            return False
        if A[n:n+len(B)]==B:
            return True

Times with this are fairly constant regardless of B (long, short, present or not). Times for the iterative solutions vary with where B starts.

To make this more robust I've tested against

A = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1]

which is longer, and repeats values.

Comments

1

You can use scipy.linalg.hankel to create all the sub-arrays in one line and then check if your array is in there. A quick example is as follows:

from scipy import linalg

A = [1,2,3,4,5,6,7,8,9,0] 

B = [4,5,6,7]

hankel_mat = linalg.hankel(A, A[::-1][:len(B)])[:-1*len(B)+1]  # Creating a matrix with a shift of 1 between rows, with len(B) columns

B in hankel_mat  # Should return True if B exists in the same order inside A 

This will not work if B is longer than A, but in that case I believe there is no point in checking :)

Comments

0
import array

def Check_array(c):
    count = 0
    count2 = 0  

    a = array.array('i',[4, 11, 20, -4, -3, 11, 3, 0, 50]);
    b = array.array('i', [20, -3, 0]);
    
    for i in range(0,len(b)):
        
        for j in range(count2,len(a)):
            if a[j]==b[i]:
                    count = count + 1
                    count2 = j
                    break           
    if count == len(b): 
        return bool (True);
    else:
        return bool (False);

res = Check_array(8)
print(res)

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
-1

By subverting your list to string, you can easily verify if the string "4567" is in the string "1234567890".

stringA = ''.join([str(_) for _ in A])
stringB = ''.join([str(_) for _ in B])

stringB in stringA 
>>> True

Dressed as a one line (cause is cooler)

isBinA = ''.join([str(_) for _ in B]) in ''.join([str(_) for _ in A])
isBinA 
>>> True

1 Comment

Does not work for some inputs : A = [45] and B = [4,5] for example.
-4
A = [1,2,3,4,5,6,7,8,9,0]
B = [4,5,6,7]

(A and B) == B

True

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.