使用Python计算DNA链的反向互补序列

13 投票
11 回答
92171 浏览
提问于 2025-04-18 16:26

我有一段DNA序列,想用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"))

11 个回答

4

反向互补序列最快的一行代码是下面这个:

def rev_compl(st):
    nn = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A'}
    return "".join(nn[n] for n in reversed(st))
16
import string
old_chars = "ACGT"
replace_chars = "TGCA"
tab = string.maketrans(old_chars,replace_chars)
print "AAAACCCGGT".translate(tab)[::-1]

这段代码会给你一个反向的互补序列,结果是 ACCGGGTTTT。

20

一般来说,生成器表达式比原来的代码更简单,而且不会创建额外的列表对象。如果需要插入多个字符,可以参考其他的答案。

complement = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A'}
seq = "TCGGGCCC"
reverse_complement = "".join(complement.get(base, base) for base in reversed(seq))
40

其他的回答都很好,但如果你打算处理真实的DNA序列,我建议你使用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
5

字典中的 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

撰写回答