处理大型 if/else 的最佳方式
Best way to handle large if/else
我有一个非常大的 if/else 块,它将对字节数组执行操作。
id 在技术上可以是从 0x001 到 0xFFF 的任何数字,但它们通常是已知的。每个案例都是唯一的,并将对数组中的不同字节执行计算。消息以大约 0.5 毫秒 - 1 毫秒的速率来自队列,并通过此方法进行处理
虽然大 if/else 有效,但我看到的最大问题是,如果在此示例中,id 为 1222,我们必须满足所有先前的 ifs。此外,随着添加的消息越来越多,时间复杂度也会增加,而且会变得非常大。
def calcCanMessage(self):
while: True
#get msg - simplified for example
msgId = msg.id
msgData = msg.data
if msgId == 324:
#do something with msgData
continue
elif msgId == 211:
continue
elif msgId == 322:
continue
elif msgId == 321:
continue
elif msgId == 320:
continue
elif msgId == 342:
continue
elif msgId == 338:
continue
elif msgId == 24:
continue
elif msgId == 212:
continue
elif msgId == 323:
continue
elif msgId == 210:
continue
elif msgId == 209:
continue
elif msgId == 208:
continue
elif msgId == 642:
continue
elif msgId == 880:
continue
elif msgId == 1088:
continue
elif msgId == 865:
continue
elif msgId == 864:
continue
elif msgId == 882:
continue
elif msgId == 1595:
continue
elif msgId == 1090:
continue
elif msgId == 885:
continue
elif msgId == 884:
continue
elif msgId == 1224:
continue
elif msgId == 1761:
continue
elif msgId == 1762:
continue
elif msgId == 1245:
continue
elif msgId == 1219:
continue
elif msgId == 1217:
continue
elif msgId == 1222:
continue
else:
print('unknown ID: ', msgId)
首先,定义与 msgData
做(不同)事情的函数。函数体将是您当前在 if..else
语句的每个块中所做的任何事情。
def msgId_324(msgData):
#do something with msgData
def msgId_211(msgData):
#do something else with msgData
# more functions to handle msgData
然后定义一个字典,将所有消息 ID 值与其对应的函数配对。
msgId_dict = {324: msgId_324,
211: msgId_211,
# more msgId: msg_function pairs
}
现在您可以用字典查找替换 if
语句,这样会更快,无论有多少消息值,并调用返回的函数。
msgId = msg.id
msgData = msg.data
if msgId in msgId_dict:
msg_function = msgId_dict[msgId]
msg_function(msgData)
else:
# optional else case to handle unrecognized message IDs
正如评论中所建议的那样,将非操作消息 ID 存储在 set
:
中
ignore_messages = {211, 322, ..., 1222}
msgId = msg.id
msgData = msg.data
if msgId == 324:
# do something with msgData
elif msgId not in ignore_messages:
print('unknown ID: ', msgId)
我有一个非常大的 if/else 块,它将对字节数组执行操作。 id 在技术上可以是从 0x001 到 0xFFF 的任何数字,但它们通常是已知的。每个案例都是唯一的,并将对数组中的不同字节执行计算。消息以大约 0.5 毫秒 - 1 毫秒的速率来自队列,并通过此方法进行处理
虽然大 if/else 有效,但我看到的最大问题是,如果在此示例中,id 为 1222,我们必须满足所有先前的 ifs。此外,随着添加的消息越来越多,时间复杂度也会增加,而且会变得非常大。
def calcCanMessage(self):
while: True
#get msg - simplified for example
msgId = msg.id
msgData = msg.data
if msgId == 324:
#do something with msgData
continue
elif msgId == 211:
continue
elif msgId == 322:
continue
elif msgId == 321:
continue
elif msgId == 320:
continue
elif msgId == 342:
continue
elif msgId == 338:
continue
elif msgId == 24:
continue
elif msgId == 212:
continue
elif msgId == 323:
continue
elif msgId == 210:
continue
elif msgId == 209:
continue
elif msgId == 208:
continue
elif msgId == 642:
continue
elif msgId == 880:
continue
elif msgId == 1088:
continue
elif msgId == 865:
continue
elif msgId == 864:
continue
elif msgId == 882:
continue
elif msgId == 1595:
continue
elif msgId == 1090:
continue
elif msgId == 885:
continue
elif msgId == 884:
continue
elif msgId == 1224:
continue
elif msgId == 1761:
continue
elif msgId == 1762:
continue
elif msgId == 1245:
continue
elif msgId == 1219:
continue
elif msgId == 1217:
continue
elif msgId == 1222:
continue
else:
print('unknown ID: ', msgId)
首先,定义与 msgData
做(不同)事情的函数。函数体将是您当前在 if..else
语句的每个块中所做的任何事情。
def msgId_324(msgData):
#do something with msgData
def msgId_211(msgData):
#do something else with msgData
# more functions to handle msgData
然后定义一个字典,将所有消息 ID 值与其对应的函数配对。
msgId_dict = {324: msgId_324,
211: msgId_211,
# more msgId: msg_function pairs
}
现在您可以用字典查找替换 if
语句,这样会更快,无论有多少消息值,并调用返回的函数。
msgId = msg.id
msgData = msg.data
if msgId in msgId_dict:
msg_function = msgId_dict[msgId]
msg_function(msgData)
else:
# optional else case to handle unrecognized message IDs
正如评论中所建议的那样,将非操作消息 ID 存储在 set
:
ignore_messages = {211, 322, ..., 1222}
msgId = msg.id
msgData = msg.data
if msgId == 324:
# do something with msgData
elif msgId not in ignore_messages:
print('unknown ID: ', msgId)