tags:

views:

136

answers:

5

I want to write a function that determines if a sublist exists in a larger list.

list1 = [1,0,1,1,1,0,0]
list2 = [1,0,1,0,1,0,1]

#Should return true
sublistExists(list1, [1,1,1])

#Should return false
sublistExists(list2, [1,1,1])

Is there a Python function that can do this?

+5  A: 

If you are sure that your inputs will only contain the single digits 0 and 1 then you can convert to strings:

def sublistExists(list1, list2):
    return ''.join(map(str, list2)) in ''.join(map(str, list1))

This creates two strings so it is not the most efficient solution but since it takes advantage of the optimized string searching algorithm in Python it's probably good enough for most purposes.

If efficiency is very important you can look at the Boyer-Moore string searching algorithm, adapted to work on lists.

A naive search has O(n*m) worst case but can be suitable if you cannot use the converting to string trick and you don't need to worry about performance.

Mark Byers
+1 for Boyer-Moore
Carlos Scheidegger
`--` : the code is seriously broken, try `sublistExists([10], [1,0])` == True?!
Nas Banov
@Nas Banov: That's why Mark wrote in his first sentence "If you are sure that your inputs will only contain single characters '0' and '1'..."
Tim Pietzcker
@Tim: But the inputs don't contain "single characters '0' and '1'", mind you! The example shown contains only the numbers `0` and `1` (or "digits" if you will). :)Besides, his code is slightly more broad - it will handle correct any list of 1-chars or any list of 1-digit numbers (but not both). And it's fairly easy to fix by introducing separator to `str.join`
Nas Banov
@Nas Banov: The usage of the word "character" was an error and is fixed now (changed to "digit"). Thanks for pointing it out.
Mark Byers
+1  A: 

No function that I know of

def sublistExists(list, sublist):
    for i in range(len(list)-len(sublist)+1):
        if sublist == list[i:i+len(sublist)]:
            return True #return position (i) if you wish
    return False #or -1

As Mark noted, this is not the most efficient search (it's O(n*m)). This problem can be approached in much the same way as string searching.

`++` : this one works, unlike the `str` -ingify solution
Nas Banov
+2  A: 

Let's get a bit functional, shall we? :)

def contains_sublist(lst, sublst):
    n = len(sublst)
    return any((sublst == lst[i:i+n]) for i in xrange(len(lst)-n+1))

Note that any() will stop on first match of sublst within lst - or fail if there is no match, after O(m*n) ops

Nas Banov
A: 

Here is a way that will work for simple lists that is slightly less fragile than Mark's

def sublistExists(haystack, needle):
    def munge(s):
        return ", "+format(str(s)[1:-1])+","
    return munge(needle) in munge(haystack)
gnibbler
A: 

if iam understanding this correctly, you have a larger list, like :

list_A= ['john', 'jeff', 'dave', 'shane', 'tim']

then there are other lists

list_B= ['sean', 'bill', 'james']

list_C= ['cole', 'wayne', 'jake', 'moose']

and then i append the lists B and C to list A

list_A.append(list_B)

list_A.append(list_C)

so when i print list_A

print (list_A)

i get the following output

['john', 'jeff', 'dave', 'shane', 'tim', ['sean', 'bill', 'james'], ['cole', 'wayne', 'jake', 'moose']]

now that i want to check if the sublist exists:

for value in list_A:
    value= type(value)
    value= str(value).strip('<>').split()[1]
    if (value == "'list'"):
        print "True"
    else:
        print "False"

this will give you 'True' if you have any sublist inside the larger list.

Suhail