在条件检查方案中替代eval

时间:2018-04-11 15:31:32

标签: python algorithm

我有这个json结构

scenarios = [{"outcome_name":"outcome1",
            "checking_condition":[
                      {
                        "db_key":"purchase_date",
                        "operator":">"
                        "db_value":"requested_date"
                         },
                      {
                        "db_key":"purchase_amount",
                        "operator":"<"
                        "db_value":"5000"  
                       }
                      ]
             outcome_selection_criteria:"index0 and index1"
             }]

因此,如果两个检查条件都为真,我将结果1标记为选择的选项,则情景列表中可能有任意数量的结果。

目前,当我动态检查条件时,我正在创建一个字符串 如购买金额的实际条件参数,字符串是:

&#34; 4000&lt; 5000&#34;我正在对此执行eval操作以获得布尔结果。 我在outcome_selection_criteria字符串中替换了相应的索引值。然后,一旦所有标准被替换,我就会对字符串执行eval以找到结果的实际结果。

然而,由于评估效率低下,我所听到的处理速度很慢。 我不太确定这是多么真实。

我正在采用这种方式,因为它允许动态处理多种类型的条件情况,而无需更改我构建的实际代码。

是否有更好的方法,而不是使用eval。

附加代码增加:

while True:

    with open(outcome_name+".json","r") as jsonfile:
         scenarios_data = json.load(jsonfile)

    for each_outcome_dict in scenarios_data:
        outcome_name = each_outcome_dict["outcome_name"]
        for ind, each_condition in enumerate(each_outcome_dict["checking_condition"]):
            key = each_condition["db_key"]
            value = each_condition["db_value"]
            operator = each_condition["operator"]
            true_key = redis_db.get(key,key)
            true_val = redis_db.get(value,value)
            condition = true_key + " " + operator + " " + true_val
            result = str(eval(condition))
            result_index = "index"+ind
            each_outcome_dict["outcome_selection_criteria"] = each_outcome_dict["outcome_selection_criteria"].replace(result_index, result)
        total_outcome = eval(each_outcome_dict["outcome_selection_criteria"])
        if total_outcome:
             outcome_name =  each_outcome_dict["outcome_name"]
             break
    else:
        print "nothing matched"
        break

1 个答案:

答案 0 :(得分:2)

将允许的运算符符号的映射定义到实现它的函数。然后,当您从条件中读取运算符时,只需查找所需的函数。

通常,operators导出的函数比使用deflambda表达式自己定义等效函数更有效。

import operators

ops = {
  "<": operator.lt,  # lambda x, y: x < y
  ">": operator.gt,  # lambda x, y: x > y
  # ...
}

for outcome in scenarios:
   for cond in outcome["checking_condition"]:
       op = cond["operator"]
       # Whatever foo is, for however you get the actual values to compare
       lhs = foo(cond["db_key"])
       rhs = foo(cond["db_value"])
       result = ops[op](lhs, rhs)
       ...