Поиск подходящих элементов на основе заданной строки

#python

#python

Вопрос:

Для простоты у меня есть этот список.

 lst = ['db', 'ca', 'db', 'ae', 'ec', 'sa']    
  

и строка 'dbaeec' , которая всегда будет иметь четную длину, в основном 6 или 8.

Мы разделим его на 2 фрагмента длины, затем возьмем первый 'db' , который найдет его, но с условием, что элемент рядом с ним должен быть 'ae' после этого 'ec'

Основываясь на приведенном выше списке, мы видим ‘db‘ с индексами 0 и 2.

Первый не соответствует ‘ae‘ для их следующего элемента и должен игнорироваться, но последний соответствует, даже для третьего ‘ec‘, и поэтому вывод должен быть 2 .

Это то, что я пробовал до сих пор,

 for i, n in enumerate(lst): 
  if n == 'db': 
      if lst[i 1] == 'ae':
          if lst[i 2] == 'ec':
              print(i)
              break
  

но наверняка должен быть лучший / pythonic способ?

Комментарии:

1. Объедините список в строку, найдите строку поиска в объединенном списке, верните половину этого индекса.

Ответ №1:

(len(string)//2) Каждый раз получайте 3 элемента, преобразуйте их в строку и сравнивайте с teststring .

 lst = ['db', 'ca', 'db', 'ae', 'ec', 'sa']    
teststring= "dbaeec"
for i in range( len(lst)-len(string)//2 ):
    if "".join( lst[i:i len(string)//2] ) == teststring:
        print(i, i len(string)//2)
        break
  

Вывод:

 2 5
  

Ответ №2:

Вот regex решение на основе. Я превратил это в повторно используемую функцию.

 import re
test_lst = ['db', 'ca', 'db', 'ae', 'ec', 'sa']
test_pat = 'dbaeec'

def find_match_index(needle, haystack):
    m = re.search(needle, ''.join(haystack))
    try:
        return (m.span()[0])/2
    except AttributeError:
        return None

def test(pat, lst):
    match = find_match_index(pat, lst)
    if match is None:
        print("No match was found (function returned None)")
    else:
        print(f"Found match at list index {match}")

print("Test with test data")
test(test_pat, test_lst)
print("Test with non-matchable pattern")
test('x', test_lst)

#output
Test with test data
Found match at list index 2.0
Test with non-matchable pattern
No match was found (function returned None)
  

Это использует тот факт, что Python является динамическим типизированным языком, возвращающим None отсутствие совпадений. Вызывающий должен проверить этот возврат. Это связано с тем, что у вас может быть допустимое совпадение с нулевым индексом, поэтому ноль не может быть флагом для not found .

Я не любитель манипулировать типами таким образом, исходя из фона C. В python нет закона, запрещающего это, но это сопряжено с рисками при дальнейшем обслуживании кода. Если бы у меня было больше времени, и это был более крупный проект, я бы создал класс «Результат» для сохранения одного типа для каждой переменной.

Ответ №3:

попробуйте это:

 y = "dbaeec"
lst = ['db', 'ca', 'db', 'ae', 'ec', 'sa']

x = ''.join(lst)    
for i in range(0, len(x), 2):
    if x[i:i len(y)] == y:
        print(i/2)
  

вывод:

 2
  

Ответ №4:

Вы можете сделать что-то вроде этого:

Это проверит dbaeec , существует ли последовательность в списке на любых последовательных позициях.

 lst = ['db', 'ca', 'db', 'ae', 'ec', 'sa']    
s = 'dbaeec'

if s in ''.join(lst):
    print ('yes')
else:
    print ('no')
  

Если вы также хотите найти позицию индекса в списке, вы можете сделать:

 lst = ['db', 'ca', 'db', 'ae', 'ec', 'sa']    
s = 'dbaeec'

i = ''.join(lst).find(s) #do a find after converting the list into a string (using join function) and then searching for dbaeec

if i >= 0:
    print ('Yes, {} is in the list starting index position {}'.format(s,int(i/2)))
else:
    print ('{} is not in the list'.format(s))
  

Вывод будет:

 Yes, dbaeec is in the list starting index position 2
  

Обратите внимание, что приведенный выше код будет искать только первое вхождение в списке. Если вы хотите найти все вхождения, код должен быть немного изменен.