【问题标题】:If statement with multiple "or" conditions?如果语句具有多个“或”条件?
【发布时间】:2019-07-31 20:04:44
【问题描述】:

我正在尝试编写一个程序,该程序遍历一串 RNA 碱基,找到起始密码子('AUG'),将以下密码子分组(即'GAA','ACC'),查找相应的字典中的氨基酸,创建一个包含生成的氨基酸的字符串,并继续运行,直到它遇到一个终止密码子('UAA','UGA','UAG')。 RNA 以三组的形式读取,从起始密码子开始,到终止密码子结束。

问题是当我想让程序检查它是否命中了三个终止密码子之一时,如果我将所有三个密码子都列在同一个 if 语句中,它就不起作用。检查字典时,它将终止密码子视为未知(.get(codon, 'X'))并将其列为蛋白质中的“X”:

a_seq = 'AAAAUGGAAUGAACC'
kmer_size = 3
for start in range (0,len(a_seq)- kmer_size+1,1):
    kmer = a_seq[start:start+kmer_size]
    if kmer == 'AUG':
        start_codon = a_seq.index(kmer)
        new_seq = a_seq[start_codon:]
        last_codon_start = len(new_seq) - 2
        dictionary = {'AUG':'M',
                     'GAA':'E',
                     'ACC':'T'}
        protein = ''
        for start in range(0, last_codon_start, 3):
            codon = new_seq[start:start+3]
            print(codon)
            if codon != 'UAA' or codon != 'UGA' or codon != 'UAG':
                amino_acid = dictionary.get(codon,'X')
                protein += amino_acid
            else:
                break
        print(protein)
        break

输出:

AUG
GAA
UAA
ACC
MEXT

如果我只列出一个终止密码子,那么它可以工作:

if codon != 'UAA':
AUG
GAA
UAA
ME

两种蛋白质都应该是“ME”。我希望它一旦碰到三个终止密码子中的任何一个就会停止。我的 if 语句有什么问题?

【问题讨论】:

  • 你应该使用and,而不是or。在您当前的状态下,所有变体都是允许的。

标签: python bioinformatics


【解决方案1】:

我认为将检查终止密码子的内部if 的逻辑颠倒过来会更具可读性:

if codon == 'UAA' or codon == 'UGA' or codon == 'UAG':

但是通过将所有可能性存储在set 中来执行等效操作会更有效,这将使检查成员身份更简单 .

这就是我的意思(请注意,我还将常量的创建排除在循环之外):

START_CODONS = {'AUG': 'M',
                'GAA': 'E',
                'ACC': 'T'}
STOP_CODONS = {'UAA', 'UGA', 'UAG'}

a_seq = 'AAAAUGGAAUGAACC'
kmer_size = 3

for start in range (0, len(a_seq)-kmer_size+1, 1):
    kmer = a_seq[start: start+kmer_size]
    if kmer == 'AUG':
        start_codon = a_seq.index(kmer)
        new_seq = a_seq[start_codon:]
        last_codon_start = len(new_seq) - 2
        protein = ''
        for start in range(0, last_codon_start, 3):
            codon = new_seq[start: start+3]
            print(codon)
#            if codon == 'UAA' or codon == 'UGA' or codon == 'UAG':
            if codon in STOP_CODONS:
                break
            else:
                amino_acid = START_CODONS.get(codon, 'X')
                protein += amino_acid
        print('protein:', protein)
        break

输出:

AUG
GAA
UGA
protein: ME

【讨论】:

    【解决方案2】:

    这会更正一行。

    if codon != 'UAA' and codon != 'UGA' and codon != 'UAG':
    

    如果你说不等于 x 或不等于 y,它总是正确的。简化一点

    if x != 1 or x !=2:
    

    无论 x 是什么,这个陈述总是正确的。每个数字都不等于both 1 和 2,包括 1 和 2。

    但这行代码最清晰的方法是。

    if codon not in ('UAA', 'UGA', 'UAG'):
    

    最后一个想法是,您可以将停止代码添加到您的字典中,并让它们产生一些您触发中断的值。这将解决@Sam Mason 关于哈希查找效率以及在主循环中节省一些其他步骤的观点。

            dictionary = {'AUG': 'M',
                          'GAA': 'E',
                          'ACC': 'T',
                          'UUA': '*',
                          'UGA': '*',
                          'UAG': '*',
            }
            protein = ''
            for start in range(0, last_codon_start, 3):
                codon = new_seq[start:start+3]
                print(codon)
                amino_acid = dictionary.get(codon,'X')
                if amino_acid == '*':
                    break
                protein += amino_acid
    

    最后的想法。使用 textwrap 模块(标准 Python)可以稍微简化 for 循环。

    from textwrap import wrap
    ...
    ...
             for codon in wrap(new_seq, 3):
                 print(codon)
                 etc.
    

    【讨论】:

    • 用更好的解决方案更新了答案。
    • 请注意,测试元组中的成员资格仍然是 O(n) 在元组中的元素数量。如果你只有几个元素,比如这里,使用元组将是相似的,但通常你想使用set,正如@martineau 建议的那样,因为它是O(1)
    • 同意 - 我应该考虑更多,所以谢谢你的评论。对于密码子,集合/元组/列表不应超过 32 个元素,因为在遗传密码中长度为 3 的序列中最多有 4 个字母的 64 个组合。正如问题所述,只有 3 个终止密码子。
    • @SamMason 感谢您的评论,我想到可以将终止密码子添加到主字典中,这将产生循环识别的值。由于字典也是一个哈希,我们可以将两个查找减少到一个。
    猜你喜欢
    • 2021-05-14
    • 2014-10-20
    • 2016-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 2014-01-09
    相关资源
    最近更新 更多