检查一个数组的所有元素是否都在另一个数组中

17

我有这两个数组:

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

并且:

B = [4,5,6,7]

有没有一种方法可以检查B是否是A中的子列表,并且顺序完全相同?


2
列表的顺序需要保持不变,对吗? - Harry
如果你的问题是这样的,那么B中元素的顺序与A中包含它的部分相同。 - iam_agf
我认为他在问元素的顺序是否重要?例如...B=[4,6,5,7] 是否同样好,或者顺序很重要? - Ryan O'Donnell
2
A和B元素的顺序很重要。就像查看B是否是列表A的一部分。 - iam_agf
有什么想法,如果我想得到剩余的数组,比如 C = A - B = [1,2,3,8,9,0]? - pandalai
8个回答

60

issubset可以帮助你。

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

例如:

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

编辑:错误,这个解决方案并不意味着元素的顺序!


7
+1,因为我发现这很有用,也感谢留下了说明,虽然它并没有完全回答问题,但会留在这里给那些可能偶然发现它的人参考。谢谢。 - Ricalsin
3
请注意,set([]).issubset(set([1,2,3])) 的运算结果为 True。 - Qlimax

10
这个怎么样:
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))

结果:

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

4

使用切片:

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

如果你的A比B大,那么类似这样的东西就会起作用。

1
这将适用于A比B小的情况,你需要关注的唯一情况是相等的长度。这个提示表明你可能应该使用range(len(A)-len(B)+1) - alko

2

我更喜欢使用index来确定起始点。在这个小例子中,它比迭代解决方案更快:

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

无论 B 是长的、短的、存在的还是不存在的,这个时间是相当恒定的。迭代解决方案的时间因 B 的起始位置而异。

为了使其更加健壮,我已经测试过以下内容:

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

哪个更长,且重复了值。


1

您可以使用scipy.linalg.hankel在一行中创建所有子数组,然后检查您的数组是否在其中。以下是一个快速示例:

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 

如果B比A长,这种方法就不起作用了,但在那种情况下,我认为检查也没有意义 :)

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
目前你的回答不够清晰。请编辑并添加更多细节,以帮助其他人理解它如何回答所提出的问题。你可以在帮助中心找到有关如何撰写好答案的更多信息。 - Community

-1
通过将您的list转换为string,您可以轻松验证字符串“4567”是否在字符串“1234567890”中。
stringA = ''.join([str(_) for _ in A])
stringB = ''.join([str(_) for _ in B])

stringB in stringA 
>>> True

穿着一行(因为更酷)

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

对于某些输入无效:例如 A = [45]B = [4,5] - Lenormju

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

(A and B) == B

True

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接