如果 dna 序列不能被三整除,有没有办法将 dna 序列列表翻译成氨基酸?

Is there a way to translate a list of dna sequences into amino acids if the dna sequence is not divisible by three?

我一直在努力将 DNA 序列列表转换为氨基酸序列。我写的函数应该读取三个核苷酸的 DNA 列表。它应该遍历列表中的序列并使用目录中的密码子翻译每个序列。现在我知道这个问题并不完全是新问题,而且 Biopython 有一个为这类问题制作的翻译模块。困难在于我后来想使用一个退化的密码子目录,带有 NNK 密码子代码(K 是 G 或 T),就我的研究而言,不可能用 Biopython 制作自定义密码子 dics。而且我用的DNA序列长度也不统一。

现在我认为是时候更深入地解释一下我的数据又名在哪里了。 DNA序列列表来自。这些序列(从 1000 个到超过 100 万个不等)是介于标记之间的随机核苷酸,我通过使用写入文本文件的正则表达式搜索的函数来分离这些标记。该文件的结构如下所示:

CACCAGAGTGAGAATAGAAA CCAAAAAAAAGGCTCCAAAAGGAGCCTTTAATTGTATC TAAACAGCTTGATACCGATAGTTGCGCCGACAATGACAACAACCATCGCCCACGCATAACCGATATATTC CCAAAAAAAAGGCTCCAAAAGGAGCCTTTAATTGTATC TAAACAGCTTGATACCGATAGTTGCGCCGACAATGACAACAACCATCGCCCACGCATAACCGATATATTC CCAAAAAAAAGGCTCCAAAAGGAGTCTTTAATTGTATC TAAACAGCTTGATACCGATAGTTGCGCCGACAATGACAACAACCATCGCCCACGCATAACCGATATATTC CCAAAAAAAGGCTCCAAAAGGAGCCTTTAATTGTATC TAAACAGCTTGATACCGATAGTTGCGCCGACAATGACAACAACCATCGCCCACGCATAACCGATATATTC CCAAAAAAAAGGCTCCAAAAGGAGCCTTTAATTGTATC TAAACAGCTTGATACCGATAGTTGCGCCGACAATGACAACAACCATCGCCCACGCATAACCGATATATTC CCAAAAAAAAGGCTCCAAAAGGAGCCTTTAATTGTATC TAAACAGCTTGATACCGATAGATGCGCCGACAATGACAACAACCATCGCCCACGCATAACCGATATATTC CAGCATTAGGAGCCGGCTGATGAGAGTGAGAATAGAAA CCAAAAAAAAGGCTCCAAAAGGAGCCTTTAATTGTATC TAAACAGCTTGATACCGATAGTTGTGCCGACAATGACAACAACCATCGCCCACGCATAACCGATATATTC

我尝试的是读取文件并获取所有序列的列表作为字符串,去除空格和换行符以及诸如此类的东西。启动一个定义了密码子用法的函数,并以三个字母的方式循环遍历每个序列的序列列表,将它们翻译成字典中密码子定义的氨基酸。

到目前为止我得到的代码:

input_file = 'inserts.txt'
with open(input_file, 'r') as f:
    seq = f.readlines()

seq = [s.replace(" ", "").replace(",", "").replace("'", "").replace("\n", "") for s in seq]
print("\n".join(seq[:99]))
print("\nType lookup", type(seq))


# translation function and NNN codon table as a dict object
def translate(seq):
    nnn_table = {'TTT': 'F', 'TCT': 'S', 'TAT': 'Y', 'TGT': 'C', 'TTC': 'F', 'TCC': 'S', 'TAC': 'Y', 'TGC': 'C',
                 'TTA': 'L',
                 'TCA': 'S', 'TAA': '*', 'TGA': '*', 'TTG': 'L', 'TCG': 'S', 'TAG': '*', 'TGG': 'W', 'CTT': 'L',
                 'CCT': 'P',
                 'CAT': 'H', 'CGT': 'R', 'CTC': 'L', 'CCC': 'P', 'CAC': 'H', 'CGC': 'R', 'CTA': 'L', 'CCA': 'P',
                 'CAA': 'Q',
                 'CGA': 'R', 'CTG': 'L', 'CCG': 'P', 'CAG': 'Q', 'CGG': 'R', 'ATT': 'I', 'ACT': 'T', 'AAT': 'N',
                 'AGT': 'S',
                 'ATC': 'I', 'ACC': 'T', 'AAC': 'N', 'AGC': 'S', 'ATA': 'I', 'ACA': 'T', 'AAA': 'K', 'AGA': 'R',
                 'ATG': 'M',
                 'ACG': 'T', 'AAG': 'K', 'AGG': 'R', 'GTT': 'V', 'GCT': 'A', 'GAT': 'D', 'GGT': 'G', 'GTC': 'V',
                 'GCC': 'A',
                 'GAC': 'D', 'GGC': 'G', 'GTA': 'V', 'GCA': 'A', 'GAA': 'E', 'GGA': 'G', 'GTG': 'V', 'GCG': 'A',
                 'GAG': 'E',
                 'GGG': 'G'}
    # two loops, outer one to loop over the list of string sequences
    # inner one loops over each sequence
    nnn_aa_seq = []
    # generate amino acid sequence
    # add option for sequence or codon not divisible by three
    print("\nStarting to translate:")
    for dna in seq:
        protein_seq = ""
        for i in range(0, len(dna), 3):
            if len(dna) % 3 == 0:
                nnn_codon = nnn_table[dna[i:i + 3]]
                protein_seq += nnn_codon
            nnn_aa_seq.append(protein_seq)

    return "".join(nnn_aa_seq)


translate_nnn = translate(seq)
print(tranlate_nnn)
# do other stuff

现在我想要的输出将是一个列表,其中包含原始文本文件中每个 DNA 序列的每个氨基酸序列。

我得到的“输出”是这样的:

Starting to translate
**T*TA*TA**TA*Y*TA*YR*TA*YR**TA*YR*L*TA*YR*LR*TA*YR*LRR*TA*YR*LRRQ*TA*YR*LRRQ**TA*YR*LRRQ*Q*TA*YR*LRRQ*QQ*TA*YR*LRRQ*QQP*TA*YR*LRRQ*QQPS*TA*YR*LRRQ*QQPSP*TA*YR*LRRQ*QQPSPT*TA*YR*LRRQ*QQPSPTH*TA*YR*LRRQ*QQPSPTHN*TA*YR*

我对这个问题的猜测是有些序列不能被三整除。对于这些序列,我认为最好移除悬垂部分或将其替换为占位符。大家怎么看?

编辑:

好吧,我忘了实际打印结果,这看起来与我想象的完全不同。它是一个不可区分的氨基酸线,而不是每个 DNA 序列的氨基酸序列列表。无论如何我的问题仍然存在。欢迎帮助和批评!

你在做

for dna in seq:
    protein_seq = ""
    for i in range(0, len(dna), 3):
        if len(dna) % 3 == 0:
            nnn_codon = nnn_table[dna[i:i + 3]]
            protein_seq += nnn_codon
        nnn_aa_seq.append(protein_seq)

这意味着您正在检查 len(dna) 是否可以被 3 整除很多次而不需要这样做。 dna 长度在每个外部 for 循环内是恒定的 运行 因此您可以在开始内部 for 循环之前检查它并提供有关它的明确信息,例如

for dna in seq:
    protein_seq = ""
    if len(dna) % 3 != 0:
        print('DNA length not divisible by 3')
        continue  # go to next element of seq
    for i in range(0, len(dna), 3):
        nnn_codon = nnn_table[dna[i:i + 3]]
        protein_seq += nnn_codon
        nnn_aa_seq.append(protein_seq)

如果你想区分结果中的序列,你不应该 return "".join(nnn_aa_seq),而是 return "\n".join(nnn_aa_seq),或者最好只 return 整个列表 return nnn_aa_seq.

至于不能全部被3整除的序列,你为什么认为这些是蛋白质编码序列?如果是,那么期望您的标记匹配模式能够准确捕获基因的起点是否现实?我在那里没有看到很多起始密码子。

如果您认为这些是基因片段,那么每个序列都有三种可能的翻译,具体取决于您如何对齐密码子框架。所以你可以尝试这样的事情:

for dna in seq:
    protein_seq_candidates = []
    for start in (0, 1, 2):
        protein_seq = []  
        for i in range(start, len(dna), 3):
            nnn_codon = nnn_table[dna[i:i + 3]]
            protein_seq.append(nnn_codon)
        protein_seq_candidates.append(protein_seq)

    # Compare the three aa sequences in terms of biological plausibility,
    # e.g. check for stop codons within the sequences, aa distribution, etc.
    # Pick the best one (or none) and append it to nnn_aa_seq.