python list and sublist
I have to check if list1 is contained in list2. It also should check if it appears in that order in the list as well. If it's true, it should return true and false if it doesn't.
def check(lst1, lst2):
for x in lst1:
for y in lst2:
xx = lst1.sort()
yy = lst2
if xx != yy:
return False
else:
return True
I'm confusing myself with 开发者_StackOverflowthe for loops and also, I don't know where to go from here to fix my code. Pointers please?
example of what it should do:
check([4,0],[9,1,4,6,8,9])
True
check([1,2],[2,3,1])
False
I thought the problem was begging to be solved recursively, so I did:
def check(needle, haystack):
if not needle:
return True
try:
offset = haystack.index(needle[0])
return check(needle[1:], haystack[offset+1:])
except:
return False
Edit:
Brief explanation:
First we check if the list we're looking for is empty (this is important once we start calling ourselves), since all lists have the empty list inside it, we return True. Then we try finding the first item of the list we're looking for in the list we're looking at. If we find it, we then call the function again, but change the arguments a bit: we already looked at the first item of the 'needle' and saw it in the 'haystack'. So now we need to check if the remainder of 'needle' is in the remainder of 'haystack'. So we call the function again only with the remainder of both lists. The remainder of needle is everything but the first element, and the remainder of haystack is all items after the one we found. If we get to a point where the first list is empty, it means we found it in the haystack. If we get an exception, what we were looking for wasn't found, so we return False, which bubbles up the call stack and gets returned.
You could start with something like:
set(lst1).issubset(lst2)
to see if lst1 is contained within lst2 ignoring order. If it passes the test that one list is contained within the other, then you could do something like:
ii = lst2.index(lst1[0])
if lst2[ii:ii+len(lst1)] == lst1:
return True
else:
return False
Originally I stated that the first check was irrelevant given the second, although you'd have to properly handle the ValueError
if the first element of lst1 is not in lst2.
Edit:
Just as a side note, I compared a version of my code vs yan's and mine is significantly faster under almost all use cases, especially if len(lst1) is larger (up to 200x speedup vs yan's implementation). Give it a try with the timeit
module.
def check(lst1,lst2):
try:
ii = lst2.index(lst1[0])
except ValueError:
return False
if lst2[ii:ii+len(lst1)] == lst1:
return True
else:
return False
As an explanation of how it works ii = lst2.index(lst1[0])
finds the index in lst2
that matches the first element of lst1
. If that item is missing from lst2
it catches the ValueError
and returns False
. If that element does exist, lst2[ii:ii+len(lst1)] == lst1
compares all of lst1
vs the sublist of lst2
starting from the matched element and taking the next len(lst)
elements.
>>> a=[9,1,4,6,8,9]
>>> by_twos=zip(a, a[1:])
>>> by_twos
[(9, 1), (1, 4), (4, 6), (6, 8), (8, 9)]
>>> (4,6) in by_twos
True
精彩评论