Поиск регулярного выражения с хотя бы одним повторением каждой буквы - PullRequest
0 голосов
/ 25 апреля 2018

Из любой последовательности ДНК * .fasta (только символы 'ACTG') я должен найти все последовательности, которые содержат хотя бы одно повторение каждой буквы.

Для примера из последовательности 'AAGTCCTAG' я должен иметь возможностьнайти: 'AAGTC', 'AGTC', 'GTCCTA', 'TCCTAG', 'CCTAG' и 'CTAG' (итерация для каждой буквы).

Я понятия не имею, как это сделать в Pyhton 2.7.Я пытался с регулярными выражениями, но он не искал все варианты.

Как я могу достичь этого?

Ответы [ 5 ]

0 голосов
/ 25 апреля 2018

Я действительно хотел создать короткий ответ для этого, поэтому я пришел к этому!

Смотрите код, используемый здесь

s = 'AAGTCCTAG'
d = 'ACGT'
c = len(d)

while c <= len(s):
    x,c = s[:c],c+1
    if all(l in x for l in d):
        print(x)
        s,c = s[1:],len(d)

Этоработает следующим образом:

  • c устанавливается на длину строки символов, которую мы гарантируем, чтобы существовать в строке (d = ACGT)
  • Итерация цикла whileпо каждой возможной подстроке s, так что c меньше длины s.
    • Это работает путем увеличения c на 1 при каждой итерации цикла while.
    • Если каждый символ в нашей строке d (ACGT) существует в подстроке,мы печатаем результат, сбрасываем c к его значению по умолчанию и срезаем строку на 1 символ от начала.
    • Цикл продолжается до тех пор, пока строка s не станет короче d

Результат:

AAGTC
AGTC
GTCCTA
TCCTAG
CCTAG
CTAG

Чтобы получить вывод в списке вместо этого ( см. Используемый код здесь ):

s = 'AAGTCCTAG'
d = 'ACGT'
c,r = len(d),[]

while c <= len(s):
    x,c = s[:c],c+1
    if all(l in x for l in d):
        r.append(x)
        s,c = s[1:],len(d)

print(r)

Результат:

['AAGTC', 'AGTC', 'GTCCTA', 'TCCTAG', 'CCTAG', 'CTAG']
0 голосов
/ 25 апреля 2018

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

def find_agtc_seq(seq_in):
    chars = 'AGTC'
    cur_str = []
    for ch in seq_in:
        cur_str.append(ch)
        while all(map(cur_str.count,chars)):
            yield("".join(cur_str))
            cur_str.pop(0)

seq = 'AAGTCCTAG'
for substr in find_agtc_seq(seq):
    print(substr)

Это может привести к тому, что вы ищете подстроки:

AAGTC
AGTC
GTCCTA
TCCTAG
CCTAG
CTAG
0 голосов
/ 25 апреля 2018

Вы можете найти все подстроки длиной 4+, а затем вниз выбрать из них, чтобы найти только самые короткие возможные комбинации, содержащие по одной из каждой буквы:

s = 'AAGTCCTAG'

def get_shortest(s):
  l, b = len(s), set('ATCG')
  options = [s[i:j+1] for i in range(l) for j in range(i,l) if (j+1)-i > 3]
  return [i for i in options if len(set(i) & b) == 4 and (set(i) != set(i[:-1]))]

print(get_shortest(s))

Вывод:

['AAGTC', 'AGTC', 'GTCCTA', 'TCCTAG', 'CCTAG', 'CTAG']
0 голосов
/ 25 апреля 2018

Это еще один способ сделать это.Может быть, не так быстро и приятно, как Крис ответил.Но, возможно, немного проще для чтения и понимания для начинающих.

DNA='AAGTCCTAG'
toSave=[]
for i in range(len(DNA)):
    letters=['A','G','T','C']
    j=i
    seq=[]
    while len(letters)>0 and j<(len(DNA)):
        seq.append(DNA[j])
        try:
            letters.remove(DNA[j])
        except:
            pass
        j+=1
    if len(letters)==0:
        toSave.append(seq)

print(toSave)
0 голосов
/ 25 апреля 2018

Если вы можете разбить последовательность на список, например, 5-буквенных последовательностей, вы можете использовать эту функцию для поиска повторяющихся последовательностей.

from itertools import groupby
import numpy as np

def find_repeats(input_list, n_repeats):
    flagged_items = []

    for item in input_list:
        # Create itertools.groupby object
        groups = groupby(str(item))

        # Create list of tuples: (digit, number of repeats)
        result = [(label, sum(1 for _ in group)) for label, group in groups]

        # Extract just number of repeats
        char_lens = np.array([x[1] for x in result])   

        # Append to flagged items
        if any(char_lens >= n_repeats):
            flagged_items.append(item)

    # Return flagged items
    return flagged_items

#--------------------------------------
test_list = ['aatcg', 'ctagg', 'catcg']

find_repeats(test_list, n_repeats=2)  # Returns ['aatcg', 'ctagg']
...