重复使用样板循环结构而不需要调用if-clause n次的pythonic方法

zea*_*oas 2 python

我继承了一个遗留代码库,其中包含大量嵌套的for循环,如下所示:

def func(infile, some_other_data, outfile, status_variable):
    with open(infile, 'r') as f:
        with open(outfile, 'w') as outf:
            for line in f:
                # parse line
                for element in some_other_data:
                    standard_function(line, element)
                    if status_variable == 'status_A':
                        function_A(line, element)
                    elif status_variable == 'status_B':
                        function_B(line, element)
                    # handle other possible status variables
                    outf.write(new_line)
Run Code Online (Sandbox Code Playgroud)

此代码与性能有关。为了加快速度(除了其他更改之外),我想消除所有被称为n * m次的if子句,测试表明,这确实可以提高10%。

为此,我只是为每个可能的状态变量复制并修改了主循环函数,并相应地调用了不同的函数。这有效地将if子句移出了循环。但是,它非常丑陋,并且使库变成了原来的4倍。

有没有一种(相当)简单的python方式来处理这种情况,在这种情况下,我想重用样板循环并只更改每次迭代所做的事情而无需每次都处理条件?

我一直在玩装饰器,它根据状态变量动态返回循环函数,并调用不同的子函数,但是从可读性的角度来看,最终结果看起来很恐怖。我绝不是python专家,所以我可能会忽略一些方便的高级功能,这些功能在这里可能会有所帮助。

任何建议都将受到高度赞赏。

n-H*_*mes 5

理想情况下,您可以传递函数本身而不是状态变量,但是由于这是遗留代码,因此一种无需更改接口的解决方案是设置函数字典,如下所示:

def func(infile, some_other_data, outfile, status_variable,
         status_functions={
             'status_A': function_A,
             'status_B': function_B,
         }
        ):

    try:
        status_function = status_functions[status_variable]
    except KeyError:
        status_function = lambda line, element: None

    with open(infile, 'r') as f, open(outfile, 'w') as outf:
        for line in f:
            # parse line
            for element in some_other_data:
                standard_function(line, element)

                status_function(line, element)
                # handle other possible status variables
                outf.write(new_line)
Run Code Online (Sandbox Code Playgroud)

  • @zeawoas因为在函数内部定义字典将需要花费一些时间来初始化和销毁​​它。如果您多次调用该函数,则可能会给整体性能带来很大的损失(尤其是在状态变量很多的情况下)。当然,在函数体中进行定义可以很好地工作,但是将其作为默认参数传递只会对其进行一次初始化。(有关更多信息,请参见[“最小惊讶”和可变默认参数](/sf/ask/79305901/)。) (2认同)

归档时间:

查看次数:

54 次

最近记录:

6 年,6 月 前