评估在python中作为字符串传入的数学表达式

时间:2016-09-13 14:54:44

标签: python python-2.7

我希望用多个变量创建一个数学函数(在这种情况下为f(x,y)),在这种情况下只有两个变量,xy,最初计算一个字符串格式的数学表达式。

例如,
如果字符串是

s = "2*x + sin(y) + x/(y-3.0)"

函数f(x,y)必须等于

def f(x,y):
    return 2*x + sin(y) + x/(y-3.0)

String在整个程序中是常量,并在开始时初始化。
该功能将被调用数千次。所以我希望它非常有效。

这样做的最佳方式是什么?

3 个答案:

答案 0 :(得分:3)

我建议你远离eval,并使用合适的图书馆来完成数学工作,最喜欢的候选人之一是同情,这被描述为:

  

SymPy是一个用于符号数学的Python库。它的目标是成为   功能齐全的计算机代数系统   (CAS)同时   保持代码尽可能简单,以便易于理解   并且易于扩展。 SymPy完全用Python编写。

有了同情心,你可以这样解决你的问题:

from sympy.parsing.sympy_parser import parse_expr

eq = parse_expr("2*x + sin(y) + x/(y-3.0)")

for x in range(4):
    for y in range(4):
        s1 = eq.subs({"x": x, "y": y})
        s2 = s1.evalf()
        print s1, "-->", s2

输出:

0 --> 0
sin(1) --> 0.841470984807897
sin(2) --> 0.909297426825682
sin(3) --> 0.141120008059867
1.66666666666667 --> 1.66666666666667
sin(1) + 1.5 --> 2.34147098480790
sin(2) + 1.0 --> 1.90929742682568
zoo --> zoo
3.33333333333333 --> 3.33333333333333
sin(1) + 3.0 --> 3.84147098480790
sin(2) + 2.0 --> 2.90929742682568
zoo --> zoo
5.00000000000000 --> 5.00000000000000
sin(1) + 4.5 --> 5.34147098480790
sin(2) + 3.0 --> 3.90929742682568
zoo --> zoo

动物园意味着“复杂的无限”。有关详细信息,请阅读docs

当然,你可以使用许多现有的python解析器之一,或者只按vz0的建议编写你的解析器。我建议您了解有关sympy的更多信息。

答案 1 :(得分:1)

如果不使用SymPy,您应该创建自己的解析器,例如converting the infix expression to a postfix expression,这在表示法中非常容易评估。数学函数只是-x等一元运算符。

答案 2 :(得分:-4)

使用eval功能 return eval(s)