重写这些多个if语句的最有效方法

时间:2015-07-06 15:12:36

标签: python python-2.7 if-statement

我知道这是一个荒谬的例子,但我正在寻找一种更有效的方式来编写这段代码。每个项目都会根据它所处的状态添加不同的值。这只是一个小片段。我可能希望将这个扩展到所有50个州,这将是很多if语句。我可以在函数中转储它,但是函数仍然会有所有的if语句。

Projects = [['Project A', 'CT', '', ''], ['Project B', 'MA', '', ''], ['Project C', 'RI', '', '']]

for project in Projects:
    if project[1] == 'CT':
        project[2] = project[0] + project[1]
        project[3] = '222'
    elif project[1] == 'MA':
        project[2] = '123'
        project[3] = None
    elif project[1] == 'ME':
        project[2] = '12323'
        project[3] = '333'
    elif project[1] == 'RI':
        project[2] = 'asdf'
        project[3] = '3333'
print Projects

2 个答案:

答案 0 :(得分:7)

使用字典映射:

for project in Projects:
    project[2:4] = {
        'CT': [project[0]+project[1], '222'],
        'MA': ['123', None],
        'ME': ['12323', '333'],
        'RI': ['asdf', '3333']
    }[project[1]]

删除所有if / else,只处理实际数据:)

正如jonrsharpe所建议的那样,用lambda来推迟对字典值的评估可能更有效率(以写更多的代价为代价):

for project in Projects:
    project[2:4] = {
        'CT': lambda: [project[0]+project[1], '222'],
        'MA': lambda: ['123', None],
        'ME': lambda: ['12323', '333'],
        'RI': lambda: ['asdf', '3333']
    }[project[1]]()

编辑:user2242044的解释:

考虑函数:

def foo(x):
    print('*** foo(%s)' % x)
    return x

,看看当你这样做时会发生什么:

>>> {1: foo(1), 2: foo(2)}[1]
*** foo(1)
*** foo(2)
1

如你所见,它计算所有字典中的值,同时调用foo(1)foo(2),然后只使用{{1}的值}。

使用foo(1) s:

lambda

字典返回一个函数,当你调用该函数时,会计算该值,因此只计算>>> {1: lambda: foo(1), 2: lambda: foo(2)}[1]() *** foo(1) 1 的值

答案 1 :(得分:2)

要扩展我的评论和mescalinum的答案,如果对n的某些影响将来自project[2]中的其他值,则可以放置可调用的对象(例如,使用lambda expressions)在词典中:

project

然后您可以像:

那样应用它
IMPACTS = {
    'CT': (lambda project: project[0] + project[1], '222'),
    'MA': ('123', None),
    ...,
}

如果某些for project in Projects: two, three = IMPACTS[project[1]] try: project[2] = two(project) except TypeError: project[2] = two project[3] = three 的值会有所不同,您可以类似地在字典中调用它们并应用相同的project[3] / try逻辑(或{{1过滤那些需要调用的东西。