简体   繁体   中英

Evaluating mathematical expressions passed in as strings in python

I wish to make a mathematical function ( f(x,y) in this case ) with multiple variables, only two in this case, x and y , which evaluates a mathematical expression which is in a string format initially.

For example,
If the string is

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

The function f(x,y) must be equivalent to

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

The String is constant throughout the program and is initialized at the start.
The function will be called thousands of times. So I wish it to be very efficient.

What is the best way to do so?

I'd recommend you stay away of eval and using a proper library to do the mathematical job at hands, one of the favourite candidates is sympy, which is described as:

SymPy is a Python library for symbolic mathematics. It aims to become a full-featured computer algebra system ( CAS ) while keeping the code as simple as possible in order to be comprehensible and easily extensible. SymPy is written entirely in Python.

With sympy, you could solve your problem like this:

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

Output:

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

zoo means "complex infinity". For more info, read the docs .

Of course, you could use one of the many existing python parsers out there or just writing yours as suggested by vz0. I'd recommend you learn more about sympy though.

Without using SymPy you should create your own parser, for example by converting the infix expression to a postfix expression , which are very easy to evaluate once in this notation. Mathematical functions are just unary operators like -x .

使用eval函数return eval(s)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM