Почему мой цикл for (python) сдвигается после 4 итераций? - PullRequest
0 голосов
/ 11 декабря 2018

Я пытаюсь написать программу, которая перемещается по элементам определенной длины последовательности ДНК, я не могу понять, какой вывод я получаю из цикла.Похоже, что смещение кадров нормально для первых четырех итераций цикла, а затем, кажется, возвращается к старым последовательностям.Я очень старался понять поведение, но я слишком новичок в программировании, чтобы решить эту проблему, любая помощь очень ценится.

Вот мой код:

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

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

Спасибо

1 Ответ

0 голосов
/ 11 декабря 2018

text.index всегда возвращает первый найденный индекс.Поскольку вы перебираете seq буква за буквой, то при первом обращении к ранее найденной букве вы получите странные результаты.

Пятая буква - это первый дубликат, 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})

Финальные попадания - это то место, где заканчивается строка, и вы можете игнорировать их.

...