iam_agf
iam_agf

Reputation: 689

Check if all elements of one array is in another array

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?

Upvotes: 20

Views: 56377

Answers (8)

Tomer Geva
Tomer Geva

Reputation: 1834

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

Upvotes: 1

Alex Von
Alex Von

Reputation: 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

Upvotes: -1

Ankit Srivastav
Ankit Srivastav

Reputation: 1

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)

Upvotes: 0

Dmitry Dubovitsky
Dmitry Dubovitsky

Reputation: 2236

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

(A and B) == B

True

Upvotes: -4

hpaulj
hpaulj

Reputation: 231665

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.

Upvotes: 2

LPH
LPH

Reputation: 1295

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!

Upvotes: 61

Akavall
Akavall

Reputation: 86326

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

Upvotes: 10

apai
apai

Reputation: 489

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.

Upvotes: 4

Related Questions