поиск набора символов отвечающего определенным параметрам в тексте

задача такая : есть некоторый текст состоящий из символов аcgt , нужно найти в нем все варианты из 10 символов , в каждом наборе a+t==g+c , длинна набора 10 символов, последние буквы g или c , не случайные наборы , а идущие по списку, как бы сканируя список некоторой "рамкой",если подходит , сохраняем, если нет то сдвигаем ее на 1 вправо , при чем искать надо не приближаясь на 60 символов вправо и лево к отмеченной знаками @ области (за пределами области)

a1=input().lower()
a,k1,k2 ,last_list1,last_list2,simv=[],[],[],[],[],['a','g','c','t','@'] #куча списков потому что я не придумал ничего лучше
for i in a1:# цикл просеивает все лишнее , пробелы , цифры и тд
    if i in simv:
        a.append(i)
ind1=a.index('@') #находим индекс разделителя, нужен для определения области поиска 
a[ind1]='!'
ind2=a.index('@')
a[ind2]='!'
list1,list2=a[0:ind1-60],a[ind2+61:len(a)+1] #разрезаем список на 2. каждый содержит только допустимую для поиска облась
for i in list1:   #  циклом наполняю список к1 до длинны в 10
    if len(k1)<10: 
        k1.append(i)
    if len(k1)==10 and (k1.count('a')+k1.count('t')==k1.count('g')+k1.count('c')) and k1[9]=='c' or k1[9]=='g' :
        last_list1.append(k1) # фильтрую по условию(длинна,соотношение букв, окончание)
    if len(k1)==10: # удаляю первый символ , что бы цикл вернувшись в начало присоединил в конец еще 1 и "сдвинул " вправо
        del k1[0]
for i in list2:
    if len(k2)<10:
        k2.append(i)
    if len(k2)==10 and (k2.count('a')+k2.count('t')==k2.count('g')+k2.count('c')) and k2[9]=='c' or k2[9]=='g' :
        last_list2.append(k2)
    if len(k2)==10:
        del k2[0]
print(last_list1,last_list2)

в конце должно получится 2 списка , но питонтьютор говорит IndexError: list index out of range в строке где проверяется условие, а intellij говорит ValueError: '@' is not in list и ее не смущает что этот символ в тексте на 5 строк выше введите сюда описание изображения я сдаюсь , спасибо если кто поможет


Ответы (1 шт):

Автор решения: GrAnd

Ну, как-то так:

valid_symbols = "agct@"

data = input()
data = "".join([v for v in data.lower() if v in valid_symbols])    # просеиваем всё лишнее, пробелы, цифры и тд
data1, _, data2 = data.split('@')  # берём части левее и правее блока @...@

found = []
for src in [data1[:-60], data2[60:]]:  # итерируемся по обеим частям, обрезанным как нам требуется
    found.append([])
    for pos in range(len(src)-10):  
        text = src[pos:pos+10]  # идём по входным данным "рамкой" длиной 10
        if text[-1] in "cg" and text.count('a')+text.count('t') == text.count('g')+text.count('c'): # проверяем наше условие
            found[-1].append(text)

print(found)
→ Ссылка