用字典代替'if-elif-else'

在实际应用中,我们经常会需要采用if-elif-else控制语句以根据不同条件,作出不同的操作。if-elif-else固然可以,但是它也存在冗余的缺点,特别是当条件较多时这一缺点尤为明显。因此,本文考虑采用字典来处理这一情况。
Python的字典是由键值对构成,键是唯一的,并且每个键都有唯一的值对应。因此,我们可以将条件控制语句中的条件作为,将相应条件下的操作作为。如果“操作”较为复杂时,我们可以将其打包为一个函数,并将此函数作为字典的“值”。
举例如下:

import numpy as np
np.random.seed(1234)
true_label = np.random.choice(np.array([0,1]), 
                              size=10000, p = [0.5, 0.5],
                              replace=True)
pred_prob = np.random.rand(10000)

metric = 'precision'
perform = np.zeros_like(pred_prob)
for j, thres in enumerate(pred_prob):
    pred_label = np.where(pred_prob>=thres, 1, 0)
    if metric == 'recall':
        perform[j] = np.logical_and(pred_label, true_label).sum()/true_label.sum()
    elif metric == 'precision':
        perform[j] = np.logical_and(pred_label, true_label).sum()/pred_label.sum()
    elif metric == 'accuracy':
        perform[j] = 1 - np.logical_xor(pred_label, true_label).sum()/pred_label.shape[0]

上述代码是利用条件控制语句,根据需要计算"召回率"、"精准率"、“准确率”,具体需要即由变量metric控制。与之对应的字典版本即为

def recall(pred_label, true_label):
    return np.logical_and(pred_label, true_label).sum()/true_label.sum()
def precision(pred_label, true_label):
    return np.logical_and(pred_label, true_label).sum()/pred_label.sum()
def accuracy(pred_label, true_label):
    return 1 - np.logical_xor(pred_label, true_label).sum()/pred_label.shape[0]

metric_dict = {'recall'   : recall,
               'precision': precision,
               'accuracy' : accuracy}
metric = 'precision'
evalua = np.zeros_like(pred_prob)
for i, thres in enumerate(pred_prob):
    pred_label = np.where(pred_prob>=thres, 1, 0)
    evalua[i]  = metric_dict.get(metric, None)(pred_label, true_label)

可以看到,条件控制语句中的操作被打包成了函数,并作为字典中的值。接下来根据键,对字典的值进行索取即可,而这里的键值即为条件,也由变量metric控制。

posted on 2023-01-13 20:59  纵横二剑  阅读(120)  评论(0编辑  收藏  举报