Checking for sublist in list

时光怂恿深爱的人放手 提交于 2020-01-10 04:31:06

问题


The Question is: You are to write a function, called isSublist(), which takes two arguments (list, sublist) and returns 1 if sublist is a sub-list of list, and 0 otherwise.

So i have my code however I get True when the sublist is not in list. Any suggestions on fixing this please?

 def isSublist(list, sublist):
    for i in range(len(list)-(len(sublist))+1):
        return True
    if sublist==list[i:i+(len(sublist))]:
        return False

sample input:

list= (0,1,2,3,4,5,6,7,8,9)
isSublist(list, [1,2,3])
output:
True

回答1:


You can break this up by getting all the slices the size of the sublist, and comparing equality:

def n_slices(n, list_):
    for i in xrange(len(list_) + 1 - n):
        yield list_[i:i+n]

def isSublist(list_, sub_list):
    for slice_ in n_slices(len(sub_list), list_):
        if slice_ == sub_list:
            return True
    return False

To cover the issue of ordering. A list is, by definition, ordered. If we want to ignore ordering, you can do sets:

def isSubset(list_, sub_list):
    return set(sub_list) <= set(list_)

If we need to cover repeated elements and ignore ordering, you're now in the realm of multisets:

def isSubset(list_, sub_list):
    for item in sub_list:
        if sub_list.count(item) > list_.count(item):
            return False
    return True



回答2:


>>> def isSublist(originallist,sublist,biglist):
    if not sublist:
        return True
    if not biglist:
        return False
    if sublist[0]==biglist[0]:
        return isSublist(originallist,sublist[1:],biglist[1:]) or isSublist(originallist,sublist,biglist[1:])
    return isSublist(originallist,originallist,biglist[1:])

test output:

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

Edited for sublists, not subset. Uglier, but works. Could add a wrapper to avoid confusion of parameters.

def sublist(a,b):
    isSublist(a,a,b)



回答3:


Part of your problem is that in Python(0,1,2,3,4,5,6,7,8,9)isn't technically alist, it's atuple -- which is essentially a immutable (unchangeable)list. Also, you should avoid naming things in your program the same as built-in functions and types, because occasionally you need to reference them and your own definition would hide the ones provided by the system.

One easy way to get around this is to just appending an_to the end of the name, as done in the following which tries to turn convert the argument into alistif it isn't one initially. It doesn't test the type of thesublist argument, but a similar check might be appropriate for it, too.

def isSublist(list_, sublist):
    if not isinstance(list_, list):
        list_ = list(list_)
    sublen = len(sublist)
    for i in xrange(len(list_)-sublen+1):
        if list_[i:i+sublen] == sublist:
            return True
    return False

list_ = (0,1,2,3,4,5,6,7,8,9)
print subfunc(list_, [0,1])  # --> True
print subfunc(list_, [1,2,3])  # --> True
print subfunc(list_, [4,6,7])  # --> False
print subfunc(list_, [4,5])  # --> True



回答4:


def isSublist(x, y):
  occ = [i for i, a in enumerate(x) if a == y[0]]
  for b in occ:
      if x[b:b+len(y)] == y:
           print 'YES-- SUBLIST at : ', b
           return True
      else:
           pass
      if len(occ)-1 ==  occ.index(b):
           print 'NO SUBLIST'
           return False

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

#should return True
isSublist(list1, [1,1,1])

#Should return False
isSublist(list2, [1,1,1])



回答5:


I've just written a recipe for this (this works for contiguous sublist):

def is_sublist(sublist, superlist):  
    ''''' 
    Checks whether 'sublist' is a sublist of 'superlist'. 
    Both arguments must be typed list or tuple. 
    '''  
    if not isinstance(sublist, (list, tuple)) or not isinstance(sublist, (list,tuple)):  
        raise TypeError("Both 'sublist' and 'superlist' must be lists or tuples.")  
    # Return early if candidate sublist is longer than superlist  
    if len(sublist) > len(superlist):  
        return False  
    else:  
        for chunk in (superlist[i:i+len(sublist)] for i in range(0, len(superlist)-len(sublist)+1)):   
            if chunk == sublist:  
                return True  
        return False

The idea is to have a shifting window (having the same width as the candidate sublist) scan the superlist and check for equality between the chunk and the sublist at each iteration.

That's a brute force method.



来源:https://stackoverflow.com/questions/19990861/checking-for-sublist-in-list

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!