Найти начальные и конечные индексы подсписка в списке

У меня есть список:

greeting = ['hello','my','name','is','bob','how','are','you']

Я хочу определить функцию, которая найдет первый и последний индекс подсписка в этом списке. Таким образом:

find_sub_list(['my','name','is'], greeting)

должен вернуться:

1, 3

Предложения?


person David Y. Stephenson    schedule 25.07.2013    source источник
comment
элементы списка всегда будут последовательными? Будет ли ['my','is','how'] также приемлемым входом? Если это вернет [1,5]   -  person misguided    schedule 26.07.2013
comment
Отвечает ли это на ваш вопрос? Python/NumPy первое вхождение подмассива   -  person Idea O.    schedule 11.05.2020


Ответы (4)


Если вам нужно несколько совпадений, это работает:

greeting = ['hello','my','name','is','bob','how','are','you','my','name','is']

def find_sub_list(sl,l):
    results=[]
    sll=len(sl)
    for ind in (i for i,e in enumerate(l) if e==sl[0]):
        if l[ind:ind+sll]==sl:
            results.append((ind,ind+sll-1))

    return results

print find_sub_list(['my','name','is'], greeting) 
# [(1, 3), (8, 10)]

Или, если вы просто хотите первое совпадение:

greeting = ['hello','my','name','is','bob','how','are','you','my','name','is']

def find_sub_list(sl,l):
    sll=len(sl)
    for ind in (i for i,e in enumerate(l) if e==sl[0]):
        if l[ind:ind+sll]==sl:
            return ind,ind+sll-1

print find_sub_list(['my','name','is'], greeting)    
# (1, 3)
person dawg    schedule 25.07.2013

Нарежьте список:

>>> greeting[0:3]
['hello', 'my', 'name']
>>> greeting[1:4]
['my', 'name', 'is']
>>> greeting[1:4] == ['my','name','is']
True

Это должно помочь вам начать:

for n in range(len(greeting) - len(sub_list) + 1):
    ...
person Blender    schedule 25.07.2013

Если вы уверены, что ваш список всегда будет в вашем подсписке, вы можете просто сделать:

def find_sub_list(sub_list,this_list):
    return (this_list.index(sub_list[0]),len(sub_list))

Если вы хотите, чтобы элементы в подсписке существовали в списке, используйте:

def find_sub_list(sub_list,this_list):
    if set(sub_list).issubset(set(this_list)): 
        return(this_list.index(sub_list[0]),len(sub_list))
    else:
        return False

Наконец, если порядок элементов в sub_list также будет неизвестен, используйте это:

def find_sub_list(sub_list,this_list):
    if sub_list[0] in this_list:
        for i,item in enumerate(sub_list[1:]):
            if item not in this_list[this_list.index(sub_list[i]):]:
                return False
        return(this_list.index(sub_list[0]),len(sub_list))

Теперь элементы должны быть в правильном порядке, чтобы функция не возвращала false.

person mbdavis    schedule 26.07.2013
comment
Ваш первый пример не будет работать для find_sub_list('ab', 'acab') - person Björn Lindqvist; 16.05.2020

Ниже приведено решение, если должны быть возвращены только индексы первой и последней записи:

def find_sub_list(subl, l):
    ind_subl = [i for i in range(len(l)) if l[i] in subl]
    return [ind_subl[0], ind_subl[-1]]

print find_sub_list(['my', 'name', 'is'], greeting)
# [1, 3]
person Francis    schedule 29.01.2018