查找DNA序列的互补序列

-1 投票
3 回答
7975 浏览
提问于 2025-04-17 09:47

我需要把DNA序列的互补序列转换成氨基酸。

TTTCAATACTAGCATGACCAAAGTGGGAACCCCCTTACGTAGCATGACCCATATATATATATATA
TATATATATATATATGGGTCATGCTACGTAAGGGGGTTCCCACTTTGGTCATGCTAGTATTGAAA
+1 TyrIleTyrIleTyrGlySerCysTyrValArgGlyPheProLeuTrpSerCysStpTyrStp
+2 IleTyrIleTyrMetGlyHisAlaThrOc*GlyGlySerHisPheGlyHisAlaSerIleglu
+3 TyrIleTyrIleTrpValMetLeuArgLysGlyValProThrLeuValMetLeuValLeuLys
  • 第一个序列是正常的DNA序列,
  • 第二个是互补序列,
  • 带有+1的那个是对应于我的互补序列的氨基酸序列,
  • 带有+2的那个是从第二个碱基开始的互补序列对应的氨基酸序列,
  • 带有+3的那个是从第三个碱基开始的互补序列对应的氨基酸序列。

我尝试了下面的代码来得到我的结果,但我只得到了一个互补序列,没有分开。

seq = "CCGGAAGAGCTTACTTAG"
basecomplement = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A'}

def translate(seq):

    x = 0
    aaseq = []
    while True:
        try:
            aaseq.append(basecomplement[seq[x:x+1]])
            x += 1

        except (IndexError, KeyError):
            break
    return aaseq

for frame in range(1):
    #print(translate(seq[frame:]))

    rseqn= (''.join(item.split('|')[0] for item in translate(seq[frame:])))

    rseqn = list(rseqn)
    rseqn.reverse()

    print( rseqn)

有人能帮我得到我的结果吗?

3 个回答

0

我把代码稍微整理了一下:

seq = "CCGGAAGAGCTTACTTAG"
basecomplement = {'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A'}

def translate(seq):
    aaseq = []
    for character in seq:
        aaseq.append(basecomplement[character])
    return aaseq

for frame in range(1):
    rseqn= (''.join(item.split('|')[0] for item in translate(seq[frame:])))
    rseqn = rseqn[::-1]
    print( rseqn)

看看这个是否适合你。

你现在做的事情是把 rseqn 转换成一个列表,然后把这个列表反转并打印出来。但我写的代码其实并没有把 rseqn 转换成列表。最开始,rseqn 是一个字符串,而那行代码 rseqn = rseqn[::-1] 是在帮你反转这个字符串。所以,最后你打印出来的是一个字符串,而不是一个列表,因此没有进行分割。

6

使用:

for frame in range(1):
    rseqn = reversed([item for item in translate(seq[frame:])])
    rseqn = ''.join(rseqn)

    print(rseqn)

这样可以生成正确的互补(反向)序列:

CTAAGTAAGCTCTTCCGG

请注意,你并不需要使用for循环(当前的这个实际上没有任何作用)来确定DNA或RNA的互补序列,因为这与翻译框架无关。

不过,我必须强调,如果你开始使用BioPython来处理生物信息学的任务,你的代码可以简化为四行:

>>> from Bio import SeqIO
>>> from Bio.Alphabet import NucleotideAlphabet
>>> dna = SeqIO.Seq("CCGGAAGAGCTTACTTAG", NucleotideAlphabet())
>>> dna.reverse_complement()
Seq('CTAAGTAAGCTCTTCCGG', NucleotideAlphabet())
>>> 
9

看起来你拿了一些代码,但并没有完全理解它的作用。如果你去看看这个链接的问题,你会发现提问者有一个用|分隔的氨基酸代码字符串的字典。调用split是为了提取每个代码字符串的第二部分,比如从"F|Phe"中你想得到"Phe",所以提问者需要用到split。而你没有那种字符串,所以不应该用那部分代码。

我同意joaquin的建议,使用BioPython,因为它显然是做这个工作的合适工具。不过为了学习,你需要知道的是,你有四个任务要完成:

  1. 计算DNA碱基序列的反向互补序列
  2. 把反向互补序列分成每组三个碱基
  3. 把每组转换成氨基酸代码
  4. 把氨基酸代码组合成一个字符串

链接中的代码没有处理第一步。为此,你可以使用Python字符串对象的translate方法。首先,你用maketrans生成一个翻译字典,将键映射到值,

basecomplement = str.maketrans({'A': 'T', 'C': 'G', 'G': 'C', 'T': 'A'})

然后你可以写一个方法来生成反向互补序列,

def reverse_complement(seq):
    return seq.translate(basecomplement)[::-1]

而joaquin在另一个问题中的translate方法实现了第二步和第三步。实际上,可以更高效地使用来自itertoolsgrouper配方。首先,你需要一个字典,将碱基三联体映射到氨基酸,

amino_acids = {'TAT': 'Tyr', ...}

然后你可以用这个字典来转换任何碱基序列,

amino_acids[''.join(a)] for a in zip(*([iter(rseq)]*3))

解释一下,zip(*([iter(rseq)]*3))是每三次把字符分为一组。但它是以元组的形式,而不是字符串,比如对于'TATATA',你会得到('T', 'A', 'T'), ('A', 'T', 'A'),所以你需要把每个元组连接成一个字符串。这就是''.join(a)的作用。然后你在氨基酸表中查找这个字符串,这一步是通过amino_acids[...]完成的。

最后,你需要把所有得到的氨基酸代码连接在一起,这可以通过外层的''.join(...)来完成。所以你可以定义一个这样的函数:

def to_amino_acids(seq):
    return ''.join(amino_acids[''.join(a)] for a in zip(*([iter(rseq)]*3)))

注意,除非你的amino_acids字典包含用|分隔的多个表示形式,否则你不需要.split('|')

最后,为了实现三种不同的碱基转氨基酸的方式,也就是三种框架,你可以使用类似于joaquin答案中最后一个循环的方式,

rseq = reverse_complement(seq)
for frame in range(3):
    # print the frame number
    print('+', frame+1, end=' ')
    # translate the base sequence to amino acids and print it
    print(to_amino_acids(rseq[frame:]))

注意,这个循环运行了三次,以打印出三种不同的框架。如果你只是想让它运行一次,那就没有必要使用循环。

撰写回答