我知道这是一个荒谬的例子,但我正在寻找一种更有效的方式来编写这段代码。每个项目都会根据它所处的状态添加不同的值。这只是一个小片段。我可能希望将这个扩展到所有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
答案 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过滤那些需要调用的东西。