Ограничение re.findall() для записи значений до определенного числа. Питон

sequence_list = ['atgttttgatggATGTTTGATTAG','atggggtagatggggATGGGGTGA','atgaaataatggggATGAAATAA']

Я беру каждый элемент (fdna) из sequence_list и ищу последовательности, начинающиеся с ATG, а затем читаю по 3, пока не достигну TAA, TGA или TAG.

Каждый элемент в sequence_list состоит из двух последовательностей. первая последовательность будет строчной, а вторая — прописной. строка результатов состоит из строчных букв + ПРОПИСНЫХ

Сбор CDS Starts & Upper()

cds_start_positions = []
cds_start_positions.append(re.search("[A-Z]", fdna).start())
fdna = fdna.upper()

Итак, после того, как я найду, где начинается последовательность в верхнем регистре, я записываю номер индекса в cds_start_positions, а затем преобразую всю строку (fdna) в верхний регистр.

Этот оператор собирает все ATG-xxx-xxx-, за которыми следует либо TAA|TAG|TGA

Сбор uORF

ORF_sequences = re.findall(r'ATG(?:...)*?(?:TAA|TAG|TGA)',fdna)

Поэтому я пытаюсь собрать все случаи, когда за ATG-xxx-xxx следует TAA, TGA или TAG.

Мои входные данные состоят из 2 последовательностей (нижний регистрUPPERCASE), и я хочу найти эти последовательности, когда:

1: за ATG следует TAA|TGA|TAG в нижнем регистре (теперь они в верхнем регистре, но значение, в котором они становятся в верхнем регистре, сохраняется в cds_start_positions)

2: ATG находится в нижнем регистре (меньше, чем значение cds_start_position), а следующий за ним TAA|TGA|TAG — в верхнем регистре.

ПРИМЕЧАНИЕ. Теперь он настроен так, что ATG, который был в исходной части верхнего регистра (больше, чем значение cds_start_position), сохраняется в списке

Что делает Gathering CDS Starts & Upper(), так это находит, где начинается последовательность верхнего регистра.

Есть ли способ наложить ограничения на часть Gathering uORF, чтобы она распознавала ATG только в позиции перед соответствующим элементом в списке cds_start_positions?

Я хочу поместить оператор в строку ORF_sequences, где он находит только «ATG» перед каждым элементом в списке «cds_start_positions».

Пример того, как будет выглядеть cds_start_positions

cds_start_positions = [12, 15, 14] #where each value indicates where the uppercase portion starts in the sequence_list elements (fdna)

для первой последовательности в sequence_list я хотел бы получить такой результат:

#input
fdna = 'atgttttgatggATGTTTGATTAG'
#what i want for the output
ORF_sequences = ['ATGTTTTGA','ATGGATGTTTGA']
#what i'm getting for the output
ORF_sequences = ['ATGTTTTGA','ATGGATGTTTGA','ATGTTTGATTAG']

эта третья запись находится после значения 12 (соответствующее значение в списке cds_start_positions), и мне это не нужно. Однако 2-я запись имеет начальный ATG до этого значения 12 и TAA|TGA|TAG после значения 12, что должно быть разрешено.

***Обратите внимание, у меня есть еще одна строка кода, которая просто берет начальные позиции, где встречаются эти ATG-xxx-xxx-TAA|TGA|TAG, а именно:

start_positions = [i for i in start_positions if i < k-1]

Есть ли способ использовать этот принцип в re.findall?

дайте мне знать, если мне нужно что-то уточнить


person O.rka    schedule 14.02.2013    source источник
comment
что произошло, когда вы запустили свой скрипт?   -  person Greg    schedule 14.02.2013
comment
Было бы полезно, если бы вы привели наименьший пример того, в чем заключается ваша проблема, показав, что у вас есть и что вы хотите, а что не будет работать. Я нахожу это сбивающим с толку тем, что используется так много языка, специфичного для предметной области. Кажется, у вас есть список строк, и вы хотите что-то от них, и ваш findall, похоже, возвращает значения, но я не знаю, в чем проблема с ними.   -  person sotapme    schedule 14.02.2013
comment
Итак, в основном вам нужна последовательность в нижнем регистре и последовательность с обоими, я прав?   -  person ATOzTOA    schedule 14.02.2013
comment
@greg Когда я запускаю скрипт, он берет последовательности ATG-xxx-xxx-TAA|TGA|TAG из комбинированного списка строчных и прописных букв. Даже последовательности, которые начинаются ПОСЛЕ соответствующего значения в cds_start_position (число)   -  person O.rka    schedule 14.02.2013
comment
@sotapme спасибо, поэтому самый маленький пример (я забыл включить его, но добавлю сейчас) состоит в том, что я получаю последовательность ATG-xxx-xxx-TAA|TGA|TAG, добавленную в мой список ORF_sequence, когда она находится после значение cds_start_position.   -  person O.rka    schedule 14.02.2013
comment
@ATOzTOA Я хочу, чтобы ATG-xxx-xxx-TAA|TGA|TAG был в нижнем регистре И когда ATG стоит перед соответствующим числовым значением в списке cds_start_positions [в приведенном примере значение было 12, поэтому, если ATG было до 12, а TAA|TGA|TAG был после значения 12 (при чтении в единицах по 3), но если ATG стоит после значения 12, игнорируйте его. прямо сейчас мой код игнорирует последовательность после значения 12   -  person O.rka    schedule 14.02.2013
comment
Вам нужно более 2 последовательностей?   -  person ATOzTOA    schedule 14.02.2013
comment
@ draconisthe0ry Когда вы снова будете на SO, взгляните на наши решения и расскажите нам, что вы о них думаете.   -  person eyquem    schedule 19.02.2013


Ответы (2)


Вчера я написал первый ответ.

Затем я прочитал ответ ATOzTOA, в котором у него была очень хорошая идея: использовать положительное ретроспективное утверждение.
Я подумал, что мой ответ полностью не соответствует действительности, и что его идея была правильным путем.
Но после этого я понял, что в коде ATOzTOA есть изъян.

Скажем, в проверяемой строке есть часть 'ATGxzyxyzyyxyATGxzxzyxyzxxzzxzyzyxyzTGA': положительное совпадение будет иметь место для 'xzyxyzyyxyATGxzxzyxyzxxzzxzyzyxyzTGA', а утвердительное совпадение — для предшествующего 'ATG', так что часть будет представлять собой совпадение; это нормально.
Но это означает, что сразу после этого сопоставления механизм регулярных выражений располагается в конце этой части 'xzyxyzyyxyATGxzxzyxyzxxzzxzyzyxyzTGA' .
Поэтому, когда механизм регулярных выражений будет искать следующее совпадение, он не найдет начала соответствия при этом 'ATG' присутствует в этой порции, так как она снова запускается с позиции намного позже нее.

.

Таким образом, единственный способ добиться того, что требуется по вопросу, - это эффективно написать первый алгоритм, который я написал, а затем я его публикую.

Работа выполняется функцией find_ORF_seq().

Если вы передадите True в качестве второго аргумента второму параметру messages функции find_ORF_seq(), она выведет сообщения, помогающие понять алгоритм.
Если нет, параметр messages принимает значение по умолчанию None.

Шаблон написан '(atg).+?(?:TAA|TGA|TAG)' с некоторыми буквами в верхнем регистре и другими в нижнем регистре, но это не причина, по которой части захватываются правильно относительно букв верхнего и нижнего регистра. Потому что, как вы увидите, используется флаг re.IGNORECASE: этот флаг необходим, поскольку часть, соответствующая (?:TAA|TGA|TAG), может попасть как в нижнюю, так и в верхнюю часть.

Суть алгоритма заключается в цикле while, который необходим из-за того, что исследуемые участки могут перекрываться, как я объяснял выше (насколько я правильно понял и приведенные вами примеры и пояснения верны).
Итак. нет возможности использовать findall() или finditer() и я делаю цикл.

Чтобы избежать повторения в последовательности fdna одного основания за другим, я использую метод ma.start(), который дает позицию начала совпадения ma в строке, и я увеличиваю значение s на s = s + p + 1. ( +1, чтобы не начинать поиск снова в начале найденного совпадения!)

Моему алгоритму не нужна информация start_positions, потому что я использую не обратное утверждение, а реальное совпадение по первым 3 буквам: совпадение объявляется неподходящим с ограничениями, когда начало совпадения находится в верхнем регистре, что сказать, когда ma.group(1), который улавливает первые три базы (это может быть 'ATG' или 'atg', так как случай игнорирования регулярного выражения), равен 'ATG'

Я был вынужден поставить s = s + p + 1 вместо s = s + p + 3, потому что кажется, что части, которые вы ищете, не разделены интервалом, кратным трем основаниям.

import re

sequence_list = ['atgttttgatgATGTTTTGATTT',
                 'atggggtagatggggATGGGGTGA',
                 'atgaaataatggggATGAAATAA',
                 'aaggtacttctcggctaACTTTTTCCAAGT']

pat = '(atg).+?(?:TAA|TGA|TAG)'
reg = re.compile(pat,re.IGNORECASE)

def find_ORF_seq(fdna,messages=None,s=0,reg=reg):
    ORF_sequences = []
    if messages:
        print 's before == ',s
    while True:
        if messages:
            print ('---------------------------\n'
                   's == %d\n'
                   'fdna[%d:] == %r' % (s,s,fdna[s:]))
        ma = reg.search(fdna[s:])
        if messages:
            print 'reg.search(fdna[%d:]) == %r' % (s,ma)
        if ma:
            if messages:
                print ('ma.group() == %r\n'
                       'ma.group(1) == %r'
                       % (ma.group(),ma.group(1)))
            if ma.group(1)=='ATG':
                if messages:
                    print "ma.group(1) is uppercased 'ATG' then I break"
                break
            else:
                ORF_sequences.append(ma.group().upper())
                p = ma.start()
                if messages:
                    print (' The match is at position p == %d in fdna[%d:]\n'
                           ' and at position s + p == %d + %d == %d in fdna\n'
                           ' then I put s = s + p + 1 == %d'
                           % (p,s, s,p,s+p, s+p+1))
                s = s + p + 1
        else:
            break
    if messages:
        print '\n==== RESULT ======\n'
    return ORF_sequences

for fdna in sequence_list:
    print ('\n============================================')
    print ('fdna == %s\n'
           'ORF_sequences == %r'
           % (fdna, find_ORF_seq(fdna,True)))

###############################

print '\n\n\n######################\n\ninput sample'
fdna = 'atgttttgatggATGTTTGATTTATTTTAG'
print '  fdna == %s' % fdna
print '  **atgttttga**tggATGTTTGATTTATTTTAG'
print '  atgttttg**atggATGTTTGA**TTTATTTTAG'
print 'output sample'
print "  ORF_sequences = ['ATGTTTTGA','ATGGATGTTTGA']"

print '\nfind_ORF_seq(fdna) ==',find_ORF_seq(fdna)

.

Та же функция без print инструкций, чтобы лучше видеть алгоритм.

import re

pat = '(atg).+?(?:TAA|TGA|TAG)'
reg = re.compile(pat,re.IGNORECASE)

def find_ORF_seq(fdna,messages=None,s =0,reg=reg):
    ORF_sequences = []
    while True:
        ma = reg.search(fdna[s:])
        if ma:
            if ma.group(1)=='ATG':
                break
            else:
                ORF_sequences.append(ma.group().upper())
                s = s + ma.start() + 1
        else:
            break
    return ORF_sequences

.

Я сравнил две функции, ATOzTOA и мою, с последовательностью fdna, обнаружившей недостаток. Это оправдывает то, что я описал.

from find_ORF_sequences import find_ORF_seq
from ATOz_get_sequences import getSequences

fdna = 'atgggatggtagatggatgggATGGGGTGA'

print 'fdna == %s' % fdna
print 'find_ORF_seq(fdna)\n',find_ORF_seq(fdna)
print 'getSequences(fdna)\n',getSequences(fdna)

результат

fdna == atgggatggtagatggatgggATGGGGTGA
find_ORF_seq(fdna)
['ATGGGATGGTAG', 'ATGGTAG', 'ATGGATGGGATGGGGTGA', 'ATGGGATGGGGTGA']
getSequences(fdna)
['ATGGGATGGTAG', 'ATGGATGGGATGGGGTGA']

.

Но в конце концов, может быть, интересно.... :
вам нужны совпадения, которые являются внутренними частями другого соответствия, например 'ATGGGATGGGGTGA' в конце 'ATGGATGGGATGGGGTGA' ?

Если нет, то подойдет и ответ АТОзТОА.

person eyquem    schedule 14.02.2013
comment
извините, я не ответил на это раньше, но это очень помогло в моих предыдущих функциях. Спасибо - person O.rka; 13.03.2013
comment
Спасибо. Ваш вопрос был интересен и я много работал над ним, поэтому мне было интересно узнать новости с вашей стороны. Я удалю свой комментарий в другом недавнем вопросе. - person eyquem; 13.03.2013

Обновление 2 – Полный код

import re

def getSequences(fdna):
    start = re.search("[A-Z]", fdna).start()
    fdna = fdna.upper()

    ORF_sequences = re.finditer(r'(?<=ATG)(.*?)(?:TAA|TAG|TGA)',fdna)

    sequences = []

    for match in ORF_sequences:
        s = match.start()
        if s < start:
            sequences.append("ATG" + match.group(0))

    print sequences

    return sequences

sequence_list = ['atgttttgatggATGTTTGATTAG','atggggtagatggggATGGGGTGA','atgaaataatggggATGAAATAA']

for fdna in sequence_list:
    getSequences(fdna)

Вывод

>>> 
['ATGTTTTGA', 'ATGGATGTTTGA']
['ATGGGGTAG', 'ATGGGGATGGGGTGA']
['ATGAAATAA', 'ATGGGGATGA']

Обновить

Если вам нужно re, попробуйте следующее:

ORF_sequences = re.finditer(r'(?<=ATG)(.*?)(?:TAA|TAG|TGA)',fdna)

for match in ORF_sequences:
    print match.span()
    print "ATG" + match.group(0)

Вывод

>>> 
(3, 9)
ATGTTTTGA
(11, 20)
ATGGATGTTTGA

Примечание

Это не всегда будет работать. Но вы можете сравнить значение match.start() с cds_start_position и удалить ненужные последовательности.


Попробуйте это, не re, но работает...

def getSequences(fdna, start):
    """Find the sequence fully to left of start and
    laying over the start"""

    i = 0
    j = 0
    f = False
    while True:
        m = fdna[i:i+3]
        if f is False:
            if m == "ATG":
                f = True
                j = i
                i += 2
        else:
            if m in ["TAA", "TAG", "TGA"]:
                i += 2
                seq1 = fdna[j: i+1]
                break

        i += 1

    i = 1
    j = 0
    f = False
    while True:
        m = fdna[i:i+3]
        if f is False:
            if m == "ATG" and i < start:
                f = True
                j = i
                i += 2
        else:
            if m in ["TAA", "TAG", "TGA"] and i > start:
                i += 2
                seq2 = fdna[j: i+1]
                break

        i += 1

    print "Sequence 1 : " + seq1
    print "Sequence 2 : " + seq2

Тест

fdna = 'atgttttgatggATGTTTGATTAG'

cds_start_positions = []
cds_start_positions.append(re.search("[A-Z]", fdna).start())

fdna = fdna.upper()

getSequences(fdna, cds_start_positions[0])

Вывод

>>> 
Sequence 1 : ATGTTTTGA
Sequence 2 : ATGGATGTTTGA
person ATOzTOA    schedule 14.02.2013
comment
с ответом «ре». я не понимаю, каков порог для исключения последовательностей? cds_start_positions указывает, где начинается заглавная часть. как версия «re» включает эти значения? - person O.rka; 15.02.2013
comment
@draconisthe0ry Как я уже упоминал в ответе, вам нужно будет сравнить значение match.start() со значениями cds_start_position. - person ATOzTOA; 15.02.2013