如何减少5层for循环的大小

时间:2018-12-21 18:52:21

标签: python optimization refactoring

我已经开发了将RNA序列翻译成肽的代码,我需要降低其缩进水平以减少空间并提高可读性

翻译的生物学概念主要在于读取3到3个字母(通常是RNA)序列,并为每个三胞胎根据表分配一个氨基酸。

获取序列并将其拆分成三胞胎的过程做得很好,并且可以重构,

seq_codons = [sequence[i:i+3] for i in range((-1 + frame), len(sequence), 3)]

但是其余只是一本巨大的字典和一个可笑的5层for循环,它可以工作,但远未优化。

这是完整的代码:

sequence = 'ACUGAUCUGAGACGUCAUCGUAGCAUCGU'


def translation(sequence, frame=1):  # Here, the frame just means from where starts
    codons_table = {                 # to count the triplets: A, C or U, in the exemple
        "CYS": ("UGU", "UGC",),
        "GLN": ("CAA", "CAG",),
        "GLU": ("GAA", "GAG",),
        "GLY": ("GGU", "GGC", "GGA", "GGG",),
        "HIS": ("CAU", "CAC",),
        "ILE": ("AUU", "AUC", "AUA",),
        "LEU": ("UUA", "UUG", "CUU", "CUC", "CUA", "CUG",),
        "LYS": ("AAA", "AAG",),
        "MET": ("AUG",),
        "PHE": ("UUU", "UUC",),
        "PRO": ("CCU", "CCC", "CCA", "CCG",),
        "SER": ("UCU", "UCC", "UCA", "UCG", "AGU", "AGC",),
        "THR": ("ACU", "ACC", "ACA", "ACG",),
        "TRP": ("UGG",),
        "TYR": ("UAU", "UAC",),
        "VAL": ("GUU", "GUC", "GUA", "GUG",),
        "STOP": ("UAG", "UGA", "UAA",),
        "ASP": ("GAU", "GAC",),
        "ASN": ("AAU", "AAC",),
        "ARG": ("CGU", "CGC", "CGA", "CGG", "AGA", "AGG",),
        "ALA": ("GCU", "GCC", "GCA", "GCG",)
    }
    seq_codons = [sequence[i:i+3] for i in range((-1 + frame), len(sequence), 3)]
    print(seq_codons)
    peptide = []

    for codon in seq_codons:
        for amino_acid, table_codon in zip(codons_table, codons_table.values()):
            if len(table_codon) > 1:
                for single_codon in table_codon:
                    if single_codon == codon:
                        peptide.append(amino_acid)
                    else:
                        pass
            else:
                if table_codon[0] == codon:
                    peptide.append(amino_acid)
                else:
                    pass

    return peptide

print(translation(sequence))

我想知道是否有办法减小最后一个for循环的大小,是否有更好的方法来存储数据,而不是使用字典

1 个答案:

答案 0 :(得分:1)

我建议您以这种方式重新映射codons_table,以便您可以直接访问(打印codons_map以了解我的意思):

codons_map = {}
for k, v in codons_table.items():
  for item in v:
    codons_map[item] = k

然后,就像您将字符串分成三部分一样:

sequence = 'ACUGAUCUGAGACGUCAUCGUAGCAUCGU'
seq_codons = [sequence[i:i+3] for i in range(0, len(sequence), 3)]

最后遍历seq_codons

peptide = []
for item in seq_codons:
  if len(item) == 3:
    peptide.append(codons_map[item])

print(peptide)
#=> ['THR', 'ASP', 'LEU', 'ARG', 'ARG', 'HIS', 'ARG', 'SER', 'ILE']


捷径

codons_map = { item: k for k, v in codons_table.items() for item in v }
seq_codons = [sequence[i:i+3] for i in range(0, len(sequence), 3)]
peptide = [ codons_map[item] for item in seq_codons if len(item) == 3 ]

print(peptide)

#=> ['THR', 'ASP', 'LEU', 'ARG', 'ARG', 'HIS', 'ARG', 'SER', 'ILE']