#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
Обратите внимание, что приведенный выше код будет искать только первое вхождение в списке. Если вы хотите найти все вхождения, код должен быть немного изменен.