Розалинда переводит РНК в белковый питон

Вот мое решение проблемы проекта Розалинд.

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', Однако, если последовательность РНА (входная строка) длиной в сотни нуклеотидов (символов), я получил ошибку:

 Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
 File "<stdin>", line 11, in prot
 KeyError: 'CUGGAAACGCAGCCGACAUUCGCUGAAGUGUAG'

Можете ли вы указать мне, где я ошибся?

3 ответа

Решение

Учитывая, что у вас есть KeyErrorпроблема должна быть в одной из ваших попыток доступа codon_table[rnaList[i]], Вы принимаете каждый элемент в rnalist три символа, но, очевидно, в какой-то момент это перестает быть True и один из предметов 'CUGGAAACGCAGCCGACAUUCGCUGAAGUGUAG',

Это происходит потому, что когда вы переназначаете rna = rna[:i]+','+rna[i:] вы меняете длинуrna, такой что твои показатели i больше не доходят до конца списка. Это означает, что для любого rna где len(rna) > 60последний элемент в списке не будет иметь длину 3. Если есть стоп-кодон, прежде чем вы достигнете элемента, это не проблема, но если вы достигнете его, вы получите KeyError,

Я предлагаю вам переписать начало вашей функции, например, используя grouper рецепт от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)

упростить ваш код.

Это не отвечает на ваш вопрос, но учтите, что вы можете решить эту проблему очень кратко, используя 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

Ваш код для разбиения РНК на блоки из 3 символов немного неприятен; Вы проводите много времени, ломая и восстанавливая строки без какой-либо реальной цели.

Сборку 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)
Другие вопросы по тегам