написание инструмента для удаления адаптера, советы по игнорированию случая в последовательности

#python #case #re

Вопрос:

Я учусь программировать. Мне нужно закодировать, среди прочего, инструмент для удаления адаптера. Мои сценарии работают нормально, за исключением случаев, когда последовательность представляет собой сочетание нижнего и верхнего регистров. последовательность переходников== Последовательность ТАТА == ТАтаГАТТАКА

Это функция для удаления адаптера

 elif operation == "adaptor-removal":

    adaptor = args.adaptor 
    reads =  sequences(args.input, format)
    num_reads = len(reads)
    bases = "".join([read["seq"] for read in reads])
    adaptors_found = 0

    for read in reads:
        for i, j in read.items():
            if i == "seq":
                if j.startswith(adaptor.upper()) or j.startswith(adaptor.lower()):
                    adaptors_found  = 1
                    j = j.replace(adaptor.upper(), "", 1) 
                    j = j.replace(adaptor.lower(), "", 1)                 
            args.output.write("%sn" % j)
    print_summary(operation)    
    print("%s adaptors found" % adaptors_found)
 

Я пытался с:

 if j.startswith(adaptor,re.I):
 

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

Большое спасибо

Ответ №1:

Давайте предположим j , что есть TAtaGATTACA и adaptor есть TATA .

Это j.startswith(adaptor.upper()) правда? Нет, потому j что с этого не начинается TATA .

Это j.startswith(adaptor.lower()) правда? Нет, потому j что с этого не начинается tata .

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

Это j.lower().startswith(adaptor.lower()) правда? Да, потому j.lower() что начинается с tata .

Кроме того, будьте осторожны с вашими двумя .replace() звонками: возможно , что один из них может привести к удалению текста дальше j , чего, я думаю, вы не хотите. Если вы просто хотите обрезать адаптер спереди j , вам лучше использовать кусочек струны:

                 if j.lower().startswith(adaptor.lower()):
                    adaptors_found  = 1
                    j = j[len(adaptor):]
 

Наконец, вы также спрашиваете, почему

 if j.startswith(adaptor,re.I):
 

не делает того, чего ты хочешь. Ответ заключается в том , что если вы передадите второй параметр .startswith() , значение этого второго параметра будет начальной позицией, из которой выполняется поиск, а не флагом, управляющим соответствием:

 "abcd".startswith("cd")           # False
"abcd".startswith("cd", 2)        # True
 

Бывает , что re.I можно преобразовать в целое число 2. Так что следующее тоже True , хотя и выглядит странно:

 "abcd".startswith("cd", re.I)
 

Комментарии:

1. вау, выглядит так просто, знаешь… Вы не можете себе представить, сколько часов я провел с ним. Большое вам спасибо.