Search code examples
pythonlistcontains

Test whether list A is contained in list B


I have two lists, A & B, and I would like to test whether A is contained in B. By "contained" I mean that the elements of A appear in the exact same order within B with no other elements between them. What I'm looking for is very similar to the behavior of A in B if they were strings.

Some elements of A will be repeated. We can assume A will be shorter than B.

There are many answers to similar questions on SO, but most answer a different question:

  • Is A an element of B? (Not my question: B is a flat list, not a list of lists.)
  • Are all the elements of A contained in B? (Not my question: I'm concerned about order as well.)
  • Is A a sublist of B? (Not my question: I don't want to know whether the elements of A appear in the same order in B, I want to know if they appear exactly as they are somewhere in B.)

If the operation were implemented as the keyword containedin, it would behave like this.

>>> [2, 3, 4] containedin [1, 2, 3, 4, 5]
True
>>> [2, 3, 4] containedin [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]
False
>>> [2, 3, 4] containedin [5, 4, 3, 2, 1]
False
>>> [2, 2, 2] containedin [1, 2, 3, 4, 5]
False
>>> [2, 2, 2] containedin [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]
False
>>> [2, 2, 2] containedin [1, 1, 1, 2, 2, 2, 3, 3, 3]
True

Is there a concise way to perform this operation in Python? Am I missing some important terminology that would have led me to the answer more quickly?


Solution

  • Use any with list slicing:

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

    Or, use join to join both lists to strings and use in operator:

    def contained_in(lst, sub):
        return ','.join(map(str, sub)) in ','.join(map(str, lst))
    

    Usage:

    >>> contained_in([1, 2, 3, 4, 5], [2, 3, 4])
    True
    >>> contained_in([1, 2, 2, 4, 5], [2, 3, 4])
    False