查找DNA序列的互补序列
我需要把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 个回答
我把代码稍微整理了一下:
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]
是在帮你反转这个字符串。所以,最后你打印出来的是一个字符串,而不是一个列表,因此没有进行分割。
使用:
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())
>>>
看起来你拿了一些代码,但并没有完全理解它的作用。如果你去看看这个链接的问题,你会发现提问者有一个用|
分隔的氨基酸代码字符串的字典。调用split
是为了提取每个代码字符串的第二部分,比如从"F|Phe"
中你想得到"Phe"
,所以提问者需要用到split
。而你没有那种字符串,所以不应该用那部分代码。
我同意joaquin的建议,使用BioPython,因为它显然是做这个工作的合适工具。不过为了学习,你需要知道的是,你有四个任务要完成:
- 计算DNA碱基序列的反向互补序列
- 把反向互补序列分成每组三个碱基
- 把每组转换成氨基酸代码
- 把氨基酸代码组合成一个字符串
链接中的代码没有处理第一步。为此,你可以使用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
方法实现了第二步和第三步。实际上,可以更高效地使用来自itertools
的grouper
配方。首先,你需要一个字典,将碱基三联体映射到氨基酸,
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:]))
注意,这个循环运行了三次,以打印出三种不同的框架。如果你只是想让它运行一次,那就没有必要使用循环。