以下是我对rosalind项目problem的解决方案。
def prot(rna):
for i in xrange(3, (5*len(rna))//4+1, 4):
rna=rna[:i]+','+rna[i:]
rnaList=rna.split(',')
bases=['U','C','A','G']
codons = [a+b+c for a in bases for b in bases for c in bases]
amino_acids = 'FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG'
codon_table = dict(zip(codons, amino_acids))
peptide=[]
for i in range (len (rnaList)):
if codon_table[rnaList[i]]=='*':
break
peptide+=[codon_table[rnaList[i]]]
output=''
for i in peptide:
output+=str(i)
return output
如果我运行prot('AUGGCCAUGGCGCCCAGAACUGAGAUCAAUAGUACCCGUAUUAACGGGUGA')
,我会得到正确的输出'MAMAPRTEINSTRING'
。但是如果rna(输入字符串)的序列长达数百个核苷酸(字符),我就会出错:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 11, in prot
KeyError: 'CUGGAAACGCAGCCGACAUUCGCUGAAGUGUAG'
你能指出我哪里出错吗?
答案 0 :(得分:2)
鉴于您有KeyError
,问题必须出在您尝试访问codon_table[rnaList[i]]
之一的问题中。您假设rnalist
中的每个项目都是三个字符,但显然,在某些时候,它停止为True
,其中一个项目为'CUGGAAACGCAGCCGACAUUCGCUGAAGUGUAG'
。
这是因为当您重新分配rna = rna[:i]+','+rna[i:]
时,更改rna
的长度,以使您的索引i
不再到达列表的末尾。这意味着对于任何rna
len(rna) > 60
,列表中的最后一项不会有长度3.如果在到达项目之前有一个终止密码子,那么这不是问题,但是如果你到达它后,您将获得KeyError
。
我建议您重写功能的开头,例如使用grouper
recipe from itertools
:
from itertools import izip_longest
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
def prot(rna):
rnaList = ["".join(t) for t in grouper(rna, 3)]
...
另请注意,您可以使用
peptide.append(codon_table[rnaList[i]])
和
return "".join(peptide)
简化您的代码。
答案 1 :(得分:1)
这不能解答您的问题,但请注意您可以使用BioPython非常简洁地解决这个问题:
from Bio.Seq import Seq
from Bio.Alphabet import IUPAC
def rna2prot(rna):
rna = Seq(rna, IUPAC.unambiguous_rna)
return str(rna.translate(to_stop=True))
例如:
>>> print rna2prot('AUGGCCAUGGCGCCCAGAACUGAGAUCAAUAGUACCCGUAUUAACGGGUGA')
MAMAPRTEINSTRING
答案 2 :(得分:0)
将rna分解为3-char块的代码有点令人讨厌;你花了很多时间打破和重建字符串,没有真正的目的。
构建codon_table只需要进行一次,而不是每次运行你的函数。
这是一个简化版本:
from itertools import product, takewhile
bases = "UCAG"
codons = ("".join(trio) for trio in product(bases, repeat=3))
amino_acids = 'FFLLSSSSYY**CC*WLLLLPPPPHHQQRRRRIIIMTTTTNNKKSSRRVVVVAAAADDEEGGGG'
codon_table = dict(zip(codons, amino_acids))
def prot(rna):
rna_codons = [rna[i:i+3] for i in range(0, len(rna) - 2, 3)]
aminos = takewhile(
lambda amino: amino != "*",
(codon_table[codon] for codon in rna_codons)
)
return "".join(aminos)