Python - 太多'elif:return()'语句?

时间:2017-06-29 03:50:18

标签: python performance if-statement

我有传递两个参数的函数:

def function(a, b):
    if   a == 'd' : return(4*b)
    elif a == '!' : return(5)
    elif a == 'k' : return(1-2*k+k**2)
    elif a == 'Z' : return(1/k)
    (...)

a正在检查它与单个字符的相等性,而b始终是一个数字;该函数也始终返回一个数字。有时它并不总是一个简单的回报。

def function(a, b):
    (...)
    elif a == '2':
        temp_b = foo(b)
        if b == 2 : temp_b += 2
        return(temp_b)

我有一个非常长的elif语句列表,有更好的方法吗?

2 个答案:

答案 0 :(得分:8)

其实是的。首先,Python没有标志性的switch语句,它在语句变得足够长时提供二进制搜索,这比线性搜索快得多。

在Python中,您可以使用具有精确值的字典或自定义函数:

def other_case(x):
    '''We can store non-lambdas too'''

    return 8

functions = {
    'd': lambda x: 4*x,
    '!': lambda x: 5,
    'k': lambda x: (1-2*x+x**2),
    'Z': lambda x: (1/x),
    '*': other_case,
}

要调用它,只需要一个简短的包装器:

def call(a, x):
    return functions[a](x)

这有O(1)时间,或者具有恒定的复杂性,因此除了更具可读性之外,它也会更快。

修改

如果您有特定范围的数字,可以在整个范围内,您还可以使用列表和转换。假设我想以100 Da的间隔处理质量为2000 Da到5000 Da(我是生物学家)的东西。编码500个项目的列表是没有意义的,但我可以使用30个项目列表来考虑整个范围。

from __future__ import division         # for //, floor division

def mass2000(x):
    '''Do something for mass of 2000'''

    return 1/x

def mass2100(x):
    '''Do something for mass of 2100'''

    return x

def mass2200(x):
    '''Do something for mass of 2200'''

    return x**2


lookup = [
    mass2000,
    mass2100,
    mass2200,
    # ....
]


def call(mass, x):
    if (mass < 2000 or mass > 5000):
        raise ValueError("Mass out of range")

    return lookup[(mass - 2000) // 100](x)

答案 1 :(得分:1)

将所有案例分成单独的迷你函数或lambda函数可能是有益的,然后有一个字典,其中键是具有相关函数/ lambda函数的字符作为值。

以下是一个例子:

def function_2(b):
    temp_b = foo(b)
    if b == 2 : temp_b += 2
    return(temp_b)

fp = {
    2 : function_2
}

然后你可以有一个循环遍历字典并匹配键,一旦匹配你可以像这样传递b。

for element in fp:
    if element == a:
        fp[element](b)