python - 优化分支逻辑

时间:2017-04-18 16:26:50

标签: python

我目前有一种令人讨厌的代码块,我正在编写一个模拟螃蟹生长的程序(令人兴奋的东西.....)。该程序后来被更大的模拟吸收,因此代码的速度很重要。我最慢的代码块之一包含这个讨厌的分支逻辑。我希望有人能想出一种方法来提高效率......

对于上下文,这段代码基本上是这样说的:"我是否正在重生爪子?如果是这样的话。如果左/右爪重新生长,它是主导还是非主导手?鉴于此,请应用此数字xyz"

if left_or_right_growing == 'left':
    if crab.rightclawCrusher == True:
        crab.rightclaw_size = new_crushersize
        if crab.moltnumber_for_claw_removal_left < crab.numberofmolts: #so it doesn't overwrite budding claw growth
            crab.leftclaw_size = max(new_pincersize * crab.proportion_of_new_claw_thats_grownback()+adj, crab.leftclaw_size)
    elif crab.rightclawCrusher == False:
        crab.rightclaw_size = new_pincersize + adj
        if crab.moltnumber_for_claw_removal_left < crab.numberofmolts: #so it doesn't overwrite budding claw growth
            crab.leftclaw_size = max(new_crushersize * crab.proportion_of_new_claw_thats_grownback(), crab.leftclaw_size)

elif left_or_right_growing == 'right':
    if crab.rightclawCrusher == True:
        crab.leftclaw_size = new_pincersize + adj
        if crab.moltnumber_for_claw_removal_right < crab.numberofmolts: #so it doesn't overwrite budding claw growth
            crab.rightclaw_size = max(new_crushersize  * crab.proportion_of_new_claw_thats_grownback(), crab.rightclaw_size)
    elif crab.rightclawCrusher == False:
        crab.leftclaw_size = new_crushersize
        if crab.moltnumber_for_claw_removal_right < crab.numberofmolts: #so it doesn't overwrite budding claw growth
            crab.rightclaw_size = max(new_pincersize  * crab.proportion_of_new_claw_thats_grownback() +adj, crab.rightclaw_size)

elif left_or_right_growing == 'both':
    pro_left, pro_right = crab.proportion_of_new_claw_thats_grownback()
    if pro_left > 1. or pro_right > 1.:
        print('ERROR IN TRANFORM:  pro_left: ' + str(pro_left) +'   pro_right:  ' + str(pro_right))
    if crab.rightclawCrusher == True:
        if crab.moltnumber_for_claw_removal_left < crab.numberofmolts: #so it doesn't overwrite budding claw growth
            crab.leftclaw_size = max(new_pincersize * pro_left+ adj, crab.leftclaw_size) 

        if crab.moltnumber_for_claw_removal_right < crab.numberofmolts:
            crab.rightclaw_size = max(new_crushersize  * pro_right, crab.rightclaw_size)                    

    else:  
        if crab.moltnumber_for_claw_removal_right < crab.numberofmolts: #so it doesn't overwrite budding claw growth
            crab.rightclaw_size = max(new_pincersize  * pro_right+ adj, crab.rightclaw_size)

        if crab.moltnumber_for_claw_removal_left < crab.numberofmolts:    
            crab.leftclaw_size = max(new_crushersize * pro_left, crab.leftclaw_size)

2 个答案:

答案 0 :(得分:2)

解决前一个人所说的你可以为你的三个条件之后出现的所有嵌套if语句创建一个函数。然后你将它们放在一本字典中,然后就这样调用它们。以下是说明此方法的示例:

def fizz(x, y):
    return x*y

def foo(k, v):
    return k - v

def buzz(a, b):
    return a + b

然后你就这样制作一本字典:

opts = {'left':fizz, 'right':foo, 'both':buzz}

然后你的代码看起来像这样:

if left_or_right_growing == 'left':
    opts['left'](1,2)
    ## output is 2

elif left_or_right_growing == 'right':
    opts['right'](3,4)
    ## output is -1

elif left_or_right_growing == 'both':
    opts['both'](5,6)
    ## output is 11

要回答你对另一个人提出的问题,是的,这种方法应该比一堆嵌套的if语句更快。在您的代码上对其进行基准测试,看看会发生什么。

编辑:使用我的方法的一些示例基准:

real    0m0.020s
user    0m0.010s
sys     0m0.007s

然后当我使用你的方法并用它自己的if循环替换函数时:

real    0m0.037s
user    0m0.012s
sys     0m0.009s

这是我用来测试函数方法的脚本:

import sys

def fizz(crab, x, y):
    if crab == 2:
        print 'Hello'
    else:
        return x*y

def foo(crab, k, v):
    if crab == 2:
        print 'Hello'
    else:
        return k - v

def buzz(crab, a, b):
    if crab == 2:
        print 'Hello'
    else:
        return a + b


opts = {'left':fizz, 'right':foo, 'both':buzz}

def main():
    left_or_right_growing = sys.argv[1]
    crab = int(sys.argv[2])
    if left_or_right_growing == 'left':
        opts['left'](crab,1,2)

    elif left_or_right_growing == 'right':
        opts['right'](crab,3,4)

    elif left_or_right_growing == 'both':
        opts['both'](crab,5,6)

if __name__ == '__main__':
    main()

要测试if循环,我只需用一个简单的if循环替换函数。正如您所看到的,即使是这样的简单任务,函数方法也会更快。

答案 1 :(得分:0)

您可以将此代码块放在一个函数中,使其看起来更干净:

if crab.rightclawCrusher == True:
            crab.rightclaw_size = new_crushersize
            if crab.moltnumber_for_claw_removal_left < crab.numberofmolts: #so it doesn't overwrite budding claw growth
                crab.leftclaw_size = max(new_pincersize * crab.proportion_of_new_claw_thats_grownback()+adj, crab.leftclaw_size)
        elif crab.rightclawCrusher == False:
            crab.rightclaw_size = new_pincersize + adj
            if crab.moltnumber_for_claw_removal_left < crab.numberofmolts: #so it doesn't overwrite budding claw growth
                crab.leftclaw_size = max(new_crushersize * crab.proportion_of_new_claw_thats_grownback(), crab.leftclaw_size)