Python:如何避免在函数中编写大量的if / elif?

时间:2016-03-01 21:49:36

标签: python

我写过一个作为计算器执行的功能。它适用于以下变量。

但是我想扩展它以处理15个不同的levels值,以及15个不同的salescost值。该功能将对每个级别应用不同的销售和成本计算,如下所示。 (由于每个计算都适用于特定级别,因此可能会在函数外部定义计算。)

我可以为15个级别中的每个级别编写大量的if / elif语句,但这似乎不是Pythonic。有没有一种方法可以以编程方式扩展这样的功能,以获得更多的销售,水平和成本?

为了清楚起见,输出将与下面相同(取决于当然输入的值),但该功能应该只能处理更多的值。

levels_list = [4, 5]  # ultimately 15 values in this list

sale4 = 18280  # ultimately 15 of these values
sale5 = 19180
sale6 = 22170

cost1 = 224 # and 15 of these values
cost2 = 335
cost3 = 456

def sales(level, foo, bar):
    for level in levels_list: 
        if level == 4:
            x = cost1 + sale4 * foo
            y = cost2 + sale4 * bar
            z = x + y
        elif level == 5:  
            x = cost2 + sale5 * foo
            y = cost3 + sale5 * bar
            z = x + y
            return pd.DataFrame({'Total Cost':[z], 'x_Cost':[x], 'y_Cost':[y]})

sales(5, 10, 10)

    Total Cost  x_Cost  y_Cost
0   384391      192135  192256

3 个答案:

答案 0 :(得分:3)

不是为每个成本和销售使用单独的变量,而是应该将它们组合成每个或列表的列表,具体取决于级别的可能值。根据您的逻辑如何处理哪些成本与哪些级别相关,这可能允许您根据级别的值访问相应的成本和销售条目

答案 1 :(得分:2)

使用dict将相关值与每个级别相关联是有意义的:

levels_dict = {4 :(sale4, cost1, cost2),
               5 :(sale5, cost2, cost3)}

这种方式levels_dict[level]将为您提供销售和计算中使用的两项费用:

def sales(level, foo, bar):
    sale, x_cost, y_cost = levels_dict[level]
    x = x_cost + sale * foo
    y = y_cost + sale * bar
    ...

如果level in range(15)始终为true,则使用列表将删除对键的需要,您可以使用列表:

levels_data =  [None, #0
                None, #1
                None, #2
                None, #3
                (18280, 224, 335),
                (19180, 335, 456)]

虽然等级从4开始,但这需要很多占位符。

最好使用namedtuple来确保始终按正确的顺序排列值:

import collections

level = collections.namedtuple("level",["sale","xcost","ycost"])

levels_dict = {4 :level(sale4, cost1, cost2),
               5 :level(sale5, cost2, cost3)}

这仍然与上面的方式相同,但也允许您使用名称而不是顺序:

def sales(level, foo, bar):
    data = levels_dict[level]
    x = data.xcost + data.sale * foo
    y = data.ycost + data.sale * bar
    ...

答案 2 :(得分:1)

您可以在DataFrame中组织数据,而不是多项,例如:

data=pd.DataFrame(np.array([[cost1,cost2,cost3],[sale4,sale5,sale6],
[cost2,cost3,cost4],[sale4,sale5,sale6]]).T,index=[3,4,5],
columns=   ['costx','salex','costy','saley'])

  costx  salex  costy  saley     
3   224  18280    335  18280
4   335  19180    456  19180
5   456  22170    512  22170

以每一行与一个级别相关联的方式。然后你的功能是立即的:

def sales(level, foo, bar):
        costx,salex,costy,saley=data.loc[level] 
        x = costx + salex * foo
        y = costy + saley * bar
        z = x + y
        return pd.DataFrame({'Total Cost':[z], 'x_Cost':[x], 'y_Cost':[y]})