有没有更有效的方法来重写多if-else语句

时间:2019-05-07 21:02:57

标签: python list dictionary

我想问的是,有一种更有效,更适当的方法来重写我的以下代码(仅仅是因为有很多if-else语句)

下面的key_list是一个列表列表,每个列表包含一些DNA碱基,例如key_list = [['-'],['A'],['A','T'],['C','G','T']]和'-'用于表示特殊间隙

我有一个主意是使用字典在这些语句之间建立映射关系,但不确定正确性。

output = []
for l in key_list:
    if len(l) == 1:
        output.append(l[0])
    elif len(l) == 2:
        if set(l) == set(['A', 'G']):
            output.append('R')
        elif set(l) == set(['C', 'T']):
            output.append('Y')
        elif set(l) == set(['A', 'C']):
            output.append('M')
        elif set(l) == set(['G', 'T']):
            output.append('K')
        elif set(l) == set(['G', 'C']):
            output.append('S')
        elif set(l) == set(['A', 'T']):
            output.append('W')
        else:
            print('Error!')
    elif len(l) == 3:
        if set(l) == set(['A', 'T', 'C']):
            output.append('H')
        elif set(l) == set(['G', 'T', 'C']):
            output.append('B')
        elif set(l) == set(['A', 'G', 'C']):
            output.append('V')
        elif set(l) == set(['A', 'T', 'G']):
            output.append('D')
        else:
            print('Error!')
    elif len(l) == 4:
        output.append('N')
    else:
        output.append('-')  # if there is only '-' in the column, also add it.

1 个答案:

答案 0 :(得分:2)

您可以使用tuple(sorted(set(l)))为字典创建密钥:

elif len(l) == 2 or len(l) == 3:
    key = tuple(sorted(set(l)))
    output.append(lookup_dict[key])

其中lookup_dict类似于:

lookup_dict = {('A', 'G') : 'R',
      ('C', 'T') : 'Y',
      ('A', 'C'): 'M',
      ('A', 'C', 'T') : 'H',   # note that it's A,C,T, not A,T,C, sort order!

 }

...等(合并长度为2和3的情况)

注释:

  • 元组按字母顺序排序,否则tuple(sorted(set(l)))不匹配。需要进行tuple转换,以便键可以可哈希list不可以)
  • 由于有了字典,查找的复杂度已从您的方法O(n)(加上无用的和多个set创建)降低到O(1)
  • 该代码不处理“错误”情况。如果没有匹配项,您将得到KeyError,可能比print('Error!')好。如果要先测试,请使用key in lookup_dict条件。

如注释中所建议,frozenset也可以用作字典键。在这种情况下,代码会更简单:

elif len(l) == 2 or len(l) == 3:
    key = frozenset(l)
    output.append(lookup_dict[key])

lookup_dict需要进行更多的预处理才能将键转换为frozenset类型(但不需要对键元素进行排序,因此不容易出错):

lookup_dict = {frozenset(k):v for k,v in lookup_dict.items()}

但是在此之后,解决方案可能会稍快一些。