Обратное дополнение цепи ДНК с использованием Python

У меня есть последовательность ДНК, и я хотел бы получить ее обратное дополнение с помощью Python. Он находится в одном из столбцов файла CSV, и я хотел бы написать обратное дополнение к другому столбцу в том же файле. Сложность в том, что есть несколько ячеек с чем-то другим, кроме A, T, G и C. Я смог получить обратное дополнение с помощью этого фрагмента кода:

def complement(seq):
    complement = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A'} 
    bases = list(seq) 
    bases = [complement[base] for base in bases] 
    return ''.join(bases)
    def reverse_complement(s):
        return complement(s[::-1])

    print "Reverse Complement:"
    print(reverse_complement("TCGGGCCC"))

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

def complement(seq):
    complement = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A'} 
    bases = list(seq) 
    for element in bases:
        if element not in complement:
            print element  
        letters = [complement[base] for base in element] 
        return ''.join(letters)
def reverse_complement(seq):
    return complement(seq[::-1])

print "Reverse Complement:"
print(reverse_complement("TCGGGCCCCX"))

person user3783999    schedule 07.08.2014    source источник
comment
Что вы хотите дополнить элементами, которых нет в словаре? Сам оригинальный товар?   -  person aa333    schedule 07.08.2014
comment
Ваш return в complement имеет неправильный отступ.   -  person jonrsharpe    schedule 07.08.2014
comment
@ aa333 Есть некоторые значения, такие как ins и dup, я бы хотел напечатать их как есть. Я пытался использовать Bio.Seq, но он преобразует «ins» в «sni» ​​при обратном дополнении.   -  person user3783999    schedule 07.08.2014
comment
сначала замените ins и другие основания однобуквенными заменителями, переверните, а затем верните их обратно   -  person Gabriel    schedule 07.08.2014
comment
@Gabriel, есть ли способ Pythonic сделать это, так как я боюсь, что не могу сделать это вручную. Спасибо   -  person user3783999    schedule 07.08.2014


Ответы (7)


Метод get словаря позволяет указать значение по умолчанию, если ключ отсутствует в словаре. В качестве предварительного шага я бы сопоставил все ваши базы без «ATGC» с отдельными буквами (или пунктуацией, или цифрами, или чем-то еще, что не будет отображаться в вашей последовательности), затем перевернул последовательность, а затем заменил отдельные буквы их оригиналами. В качестве альтернативы вы можете сначала изменить его, а затем найти и заменить такие вещи, как sni на ins.

alt_map = {'ins':'0'}
complement = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A'} 

def reverse_complement(seq):    
    for k,v in alt_map.iteritems():
        seq = seq.replace(k,v)
    bases = list(seq) 
    bases = reversed([complement.get(base,base) for base in bases])
    bases = ''.join(bases)
    for k,v in alt_map.iteritems():
        bases = bases.replace(v,k)
    return bases

>>> seq = "TCGGinsGCCC"
>>> print "Reverse Complement:"
>>> print(reverse_complement(seq))
GGGCinsCCGA
person Gabriel    schedule 07.08.2014
comment
Спасибо за твой ответ. Я не могу жестко закодировать элемент «alt», потому что это может быть что угодно. Для него нет определенной структуры. - person user3783999; 07.08.2014
comment
обновил ответ на работу, не зная, какими будут другие базы - person Gabriel; 07.08.2014
comment
Просто используйте complement.get(base,base). - person aa333; 07.08.2014
comment
Если вы хотите опубликовать это где-нибудь, остерегайтесь неоднозначных кодов. - person Audrius Meskauskas; 18.08.2016
comment
Самый быстрый и понятный способ перевернуть строку: your_string[::-1] - person Mastodon; 19.04.2017

Другие ответы вполне хороши, но если вы планируете иметь дело с реальными последовательностями ДНК, я предлагаю использовать Biopython. Что, если вы столкнетесь с такими символами, как -, * или неопределенность? Что делать, если вы хотите выполнить дальнейшие манипуляции со своими последовательностями? Вы хотите создать анализатор для каждого формата файла?

Код, который вы запрашиваете, так же прост, как:

from Bio.Seq import Seq

seq = Seq("TCGGGCCC")

print seq.reverse_complement()
# GGGCCCGA

Теперь, если вы хотите сделать другие преобразования:

print seq.complement()
print seq.transcribe()
print seq.translate()

Выходы

AGCCCGGG
UCGGGCCC
SG

И если вы столкнетесь со странными символами, вам не нужно будет продолжать добавлять код в свою программу. Biopython справляется с этим:

seq = Seq("TCGGGCCCX")
print seq.reverse_complement()
# XGGGCCCGA
person xbello    schedule 07.08.2014

В целом выражение генератора проще, чем исходный код, и позволяет избежать создания дополнительных объектов списка. Если могут быть вставки из нескольких символов, используйте другие ответы.

complement = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A'}
seq = "TCGGGCCC"
reverse_complement = "".join(complement.get(base, base) for base in reversed(seq))
person Jason S    schedule 07.08.2014
comment
зачем тебе (base, base) два раза здесь? - person Igor Barinov; 16.08.2015
comment
@IgorBarinov: функция get имеет тип возвращаемого значения по умолчанию None, когда ключ недоступен. Установка base в качестве типа возвращаемого значения по умолчанию позволяет избежать KeyError и просто вставляет значение для base. В результате необычные символы в последовательности теперь обрабатываются (правильно). - person Steve; 28.02.2017

import string
old_chars = "ACGT"
replace_chars = "TGCA"
tab = string.maketrans(old_chars,replace_chars)
print "AAAACCCGGT".translate(tab)[::-1]

это сделает вам обратный комплимент = ACCGGGTTTT

person Nathan M    schedule 28.10.2014
comment
Лучший ответ для меня. Обратите внимание, что его необходимо адаптировать для python3: заменить string на str (импортировать не нужно) и, очевидно, добавить скобки к print. - person Jean Paul; 26.11.2018
comment
ответил 28 окт. Отличное наблюдение. - person Nathan M; 01.12.2018

Попробуйте код ниже,

complement = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A'}
seq = "TCGGGCCC"
reverse_complement = "".join(complement.get(base, base) for base in reversed(seq))
person Akansha Rana    schedule 23.09.2019
comment
Добавьте форматирование кода в свой пост. Кроме того, рассмотрите возможность добавления каких-либо пояснений к вашему решению. - person Pochmurnik; 23.09.2019

Самый быстрый лайнер для обратного дополнения следующий:

def rev_compl(st):
    nn = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A'}
    return "".join(nn[n] for n in reversed(st))
person alphahmed    schedule 05.02.2020
comment
Лучший ответ для чистого Python - person Can H. Tartanoglu; 12.05.2021

Учитывая также вырожденные базисы:

def rev_compl(seq):
    BASES ='NRWMBDACGTHVKSY'
    return ''.join([BASES[-j] for j in [BASES.find(i) for i in seq][::-1]])
person msim    schedule 06.06.2021