Почему мой цикл for (python) сдвигается после 4 итераций?
Я пытаюсь написать программу, которая перемещается по элементам определенной длины последовательности ДНК, я не могу понять, какой вывод я получаю из цикла. Похоже, что смещение кадров нормально для первых четырех итераций цикла, а затем, кажется, возвращается к старым последовательностям. Я очень старался понять поведение, но я слишком новичок в программировании, чтобы решить эту проблему, любая помощь очень ценится.
Вот мой код:
seq = "ACTGCATTTTGCATTTT"
search = "TGCATTTTG"
import regex as re
def kmers(text,n):
for a in text:
b = text[text.index(a):text.index(a)+n]
c = len(re.findall(b, text, overlapped=True))
print ("the count for " + b + " is " + str(c))
(kmers(seq,3))
и мой вывод:
the count for ACT is 1
the count for CTG is 1
the count for TGC is 2
the count for GCA is 2
#I expected 'CAT' next, from here on I don't understand the behaviour
the count for CTG is 1
the count for ACT is 1
the count for TGC is 2
the count for TGC is 2
the count for TGC is 2
the count for TGC is 2
the count for GCA is 2
the count for CTG is 1
the count for ACT is 1
the count for TGC is 2
the count for TGC is 2
the count for TGC is 2
the count for TGC is 2
Очевидно, в конце концов я хочу удалить дубликаты и т. Д., Но застрял на том, почему мой цикл for не работает, как я ожидал, остановил меня в моих треках, чтобы сделать это лучше.
Спасибо
1 ответ
text.index
всегда возвращает первый найденный индекс Так как вы повторяете свой seq
буква за буквой, когда вы впервые нажмете на ранее найденную букву, вы получите странные результаты.
5-я буква - первый дубликат, c
, так что text.index('c')
возвращает индекс первого c
, 1, а не 4, как вы ожидаете - и вы дублируете предыдущий раз, когда вы нажмете c
,
Этот метод неэффективен - кажется, что вас больше интересует перемещение по индексам, чем по буквам, поэтому я бы использовал:
for a in range(len(text)-(n-1)):
b = text[a:a+n]
c = len(re.findall(b, text, overlapped=True))
print ("the count for " + b + " is " + str(c))
Вместо поиска индекса каждый раз, который неэффективен и в вашем случае дает неправильные результаты. findall
здесь тоже неэффективный способ подсчета - словарь, конкретно defaultdict
может быть построен, чтобы рассчитывать более эффективно.
Обратите внимание, что уже есть хорошие встроенные функции, которые вы можете использовать:
>>> from collections import Counter
>>> seq='ACTGCATTTTGCATTTT'
>>> Counter((seq[i:i+3] for i in range(len(seq)-2)))
Counter({'TTT': 4, 'TGC': 2, 'GCA': 2, 'CAT': 2, 'ATT': 2, 'ACT': 1, 'CTG': 1, 'TTG': 1})
Финальные попадания - это то, где заканчивается строка, и вы можете не обращать на них внимания.