Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if all elements in a list are present and in the same order in another list

How do I create a function sublist() that takes two lists, list1 and list2, and returns True if list1 is a sublist of list2, and False otherwise. list1 is a sublist of list2 if the numbers in list1 appear in list2 in the same order as they appear in list1, but not necessarily consecutively. For example,

>>> sublist([1, 12, 3],[25, 1, 30, 12, 3, 40])
True

>>> sublist([5, 90, 2],[90, 20, 5, 2, 17])
False
like image 847
user3638865 Avatar asked May 15 '14 01:05

user3638865


People also ask

How do you check if all elements in a list are present in another list?

There are 2 ways to understand check if the list contains elements of another list. First, use all() functions to check if a Python list contains all the elements of another list. And second, use any() function to check if the list contains any elements of another one.

How do you see if an item in a list is in another list Python?

To check if the item exists in the list, use Python “in operator”. For example, we can use the “in” operator with the if condition, and if the item exists in the list, then the condition returns True, and if not, then it returns False.

How do you check if any elements in a list are the same?

Using Count() The python list method count() returns count of how many times an element occurs in list. So if we have the same element repeated in the list then the length of the list using len() will be same as the number of times the element is present in the list using the count().


3 Answers

Here's one way to do it in linear time (and constant space) with an iterator:

def sublist(a, b):
    seq = iter(b)
    try:
        for x in a:
            while next(seq) != x: pass
        else:
            return True
    except StopIteration:
        pass
    return False

Basically it goes through each element of the sublist, and sees if it can find that same element in the part of the complete list it hasn't looked at yet. If it makes it through the entire sublist it means we have a match (hence the else statement on the for loop). If we run out of elements to look at in the complete list, it means we don't have a match.

Edit: I have updated my solution so it works with Python 3. For Python 2.5 and older, next(seq) needs to be replaced with seq.next().

like image 101
hetman Avatar answered Oct 08 '22 21:10

hetman


A very rough solution:

def sublist(a, b):
    if not a:
        return True
    for k in range(len(b)):
        if a[0] == b[k]:
            return sublist(a[1:], b[k+1:])
    return False

print sublist([1, 12, 3], [25, 1, 30, 12, 3, 40]) # True
print sublist([12, 1, 3], [25, 1, 30, 12, 3, 40]) # False

Edit: Speed upgrade

like image 5
huu Avatar answered Oct 08 '22 22:10

huu


Here's an iterative solution which should have optimal asymptotics:

def sublist(x, y):
    if x and not y:
        return False
    i, lim = 0, len(y)
    for e in x:
        while e != y[i]:
            i += 1
            if i == lim:
                return False
        i += 1
    return True

@sshashank124's solution has the same complexity, but the dynamics will be somewhat different: his version traverses the second argument multiple times, but because it pushes more work into the C layer it'll probably be much faster on smaller input.

Edit: @hetman's solution has essentially the same logic, but is much more Pythonic, although, contrary to my expectation, it seems to be slightly slower. (I was also incorrect about the performance of @sshashan124's solution; the overhead of the recursive calls appears to outweigh the benefit of doing more work in C.)

like image 2
Alp Avatar answered Oct 08 '22 20:10

Alp