Python评估速度和性能

时间:2019-06-10 19:09:45

标签: python django

我有字典 说

prices={
    "set1": {
        "price1": 200,
        "price2": 300
         ....
    },
    "set2": {
        "price1": 200,
        "price2": 300,
        ....

    }
}

我有一套规则。 说

rules={
    "set1": {
        "a>0 and b<10 and price1>300": 1.5,
        "a+b=10 or c>20": 2.5
         ....
    },
    "set2": {
        "a=c and b!=d or price2<100": 3.5,
        "a=b and price2 in range(100,300)": 4,
        ....

    }
}

这里a,b,c,d ..是用某些值定义的变量 如果相应集中的任何规则都满足,则会将其添加到prices中的价格中。

现在我正在使用 if eval(rule) for for循环 但是总共有大约20000个循环,因此至少需要5分钟才能执行。

是否可以选择使其更快?

我正在为此API使用Django框架

编辑: 当我使用lambda 它显示错误为未定义变量

1 个答案:

答案 0 :(得分:0)

对于这种类型的过程,您应该使用lambda或函数。为此,您需要确保在lambda或函数中使用的变量在规则字典的声明范围内。但是,如果您的代码和规则声明不包含在单个函数中,则可能会很难做到。

您尚未发布足够的上下文信息/代码来确定我们的方法失败的地方,但是也许有一个示例可以使您走上正确的轨道:

prices={
    "set1": {
        "price1": 200,
        "price2": 300
    },
    "set2": {
        "price1": 200,
        "price2": 250
    }
}

def Rule(expression,priceValue):
    return (compile(expression,"<string>","eval"),priceValue)

rules={
    "set1": [
        Rule("a>0 and b<10 and price1>300",1.5),
        Rule("a+b==10 or c>20",2.5)
    ],
    "set2": [
        Rule("a==c and b!=d or price2<100",3.5),
        Rule("a==b and price2 in range(100,300)",4)
    ]
}

context = { "a":5, "b":5, "c":5, "d":0 }
for setId,priceSet in prices.items():
    price = []
    for rule,value in rules[setId]:
        context.update(priceSet)
        if eval(rule,globals(),context):
            price.append(value)
    print(setId,price,sum(price))

# set1 [2.5] 2.5
# set2 [3.5, 4] 7.5 
  • 要使重复的eval()函数调用更快,可以使用compile() 获得您的字符串公式的“编译”版本。这是什么 您应该将其存储在规则字典中。
  • 规则集的内容只需是一个元组数组。这个 将使使用规则列表更加容易。
  • 在示例规则表达式中,您使用的是单个等号 (=)测试相等性,否则Python需要双等号 这些公式不会产生预期的结果。

我不确定您所说的“它将增加价格中的价格” 。由于您的规则已经在其表达式中使用了price1和price2,因此它们似乎需要价格字典(或其至少其中之一)的内容才能产生答案。为什么然后(以及如何)他们将更新他们依赖于响应的数据结构?并用什么键?我无法提供满足该要求的示例。希望您能够根据您的需求调整我的榜样。