【问题标题】:Evaluating math expressions in a string in python在python中评估字符串中的数学表达式
【发布时间】:2020-12-22 08:02:43
【问题描述】:

我有一堆从JSON file 加载的方程,我想评估这些表达式。这些表达式有一些常量,常量的值(K1K2,...)也保存在 json 文件中。与表达式中存在的变量 (var1, var2 ...) 对应的值在字典 vars 中定义。我想在表达式中插入常量和变量的值并计算数值。

import json
vars = {"var1": 1, "var2": 2, "var3": 3, "var4": 4, "var5": 5, "var6": 5}
with open("tst.json", 'r') as f:
     r = json.load(f)
     print(r)

json 内容:

{
  "EQ1": {
    "parameters": {
      "EQ1_coeff1": {
        "value": 1.0e-06
      },
      "P2": {
        "value": 3.0
      },
      "P3": {
        "value": 3.0
      }
    },
    "expression": "(EQ1_coeff1 * ((1 dimensionless)/(1 dimensionless)) / (1 dimensionless))*(var1^P3/(var1^P3 + P2^P3) )"
  },
  "EQ2": {
    "parameters": {
      "EQ2_coeff2": {
        "value": 5253
      },
      "K2": {
        "value": 3
      },
      "K5": {
        "value": 1
      },
      "K3": {
        "value": 525
      },
      "K4": {
        "value": 3
      },
      "K6": {
        "value": 2
      },
      "K7": {
        "value": 0.01
      }
    },
    "expression": "(EQ2_coeff2 *((var2*var3)/(K1*K2))* ((1 dimensionless - ((var3*var4)/(var2))/K6) / ((1 dimensionless + var1/K1)*(1 dimensionless + var2)+ 1 dimensionless)))*(1 dimensionless/(1 dimensionless + var5/K7))"
  }
}

我想就如何计算这些表达式(存储在expression)寻求建议。

旁注:

1 dimensionless 只不过是 1。

【问题讨论】:

    标签: python-3.x equation-solving mathematical-expressions


    【解决方案1】:

    我将简单地将globals() 更新为dict,然后使用eval,如下所示:

    import json
    vars = {"var1": 1, "var2": 2, "var3": 3, "var4": 4, "var5": 5, "var6": 5}
    r = {
      "EQ1": {
        "parameters": {
          "EQ1_coeff1": {
            "value": 1.0e-06
          },
          "P2": {
            "value": 3.0
          },
          "P3": {
            "value": 3.0
          }
        },
        "expression": "(EQ1_coeff1 * ((1 dimensionless)/(1 dimensionless)) / (1 dimensionless))*(var1^P3/(var1^P3 + P2^P3) )"
      },
      "EQ2": {
        "parameters": {
          "EQ2_coeff2": {
            "value": 5253
          },
          "K2": {
            "value": 3
          },
          "K5": {
            "value": 1
          },
          "K3": {
            "value": 525
          },
          "K4": {
            "value": 3
          },
          "K6": {
            "value": 2
          },
          "K7": {
            "value": 0.01
          }
        },
        "expression": "(EQ2_coeff2 *((var2*var3)/(K1*K2))* ((1 dimensionless - ((var3*var4)/(var2))/K6) / ((1 dimensionless + var1/K1)*(1 dimensionless + var2)+ 1 dimensionless)))*(1 dimensionless/(1 dimensionless + var5/K7))"
      }
    }
    
    globals().update( **{k:v['value'] for k,v in r["EQ1"]["parameters"].items()})
    globals().update( **{k:v['value'] for k,v in r["EQ2"]["parameters"].items()})
    globals().update(**vars)
    
    eval(r['EQ1']['expression'].replace("dimensionless", "").replace("^", "**"))
    

    这给出:3.571428571428571e-08

    对于EQ2,您没有定义变量K1。这更像是一种 hack,不过我不知道有一种更优雅的方式。还要记住eval 不是很安全的功能。

    【讨论】:

    • 非常感谢,它有帮助!你能告诉我以什么形式的表达式评估Also keep in mind eval is a not very safe function这是不安全的。
    • 我很乐意提供帮助 :)。如果您从不受信任的来源获取字符串,eval 可能会导致麻烦。某些恶意字符串在执行时会造成严重损害。
    • 感谢您的澄清。另外,您能否解释一下全球的运作方式。非常感谢!
    • globals() 返回一个字典,它告诉全局范围内的所有可用变量。这个答案很有启发性stackoverflow.com/a/12694065/4551984
    猜你喜欢
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-30
    • 1970-01-01
    • 2022-01-17
    • 1970-01-01
    相关资源
    最近更新 更多