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