Evaluating mathematical expressions passed in as strings in python
<p><p> I wish to make a mathematical function ( <code>f(x,y)</code> in this case ) with multiple variables, only two in this case, <code>x</code> and <code>y</code>, which evaluates a mathematical expression which is in a string format initially.
<p>
For example,<br>
If the string is</p>

<pre><code>s = "2*x + sin(y) + x/(y-3.0)"
</code></pre>

<p>The function f(x,y) must be equivalent to</p>

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

<p>The String is constant throughout the program and is initialized at the start.
<bR>The function will be called thousands of times. So I wish it to be very efficient. 
<p>
What is the best way to do so?</p>

<p>I'd recommend you stay away of <a href="http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html" rel="nofollow">eval</a> and using a proper library to do the mathematical job at hands, one of the favourite candidates is sympy, which is described as:</p>

<blockquote>
  <p>SymPy is a Python library for symbolic mathematics. It aims to become
  a full-featured computer algebra system
  (<a href="https://en.wikipedia.org/wiki/Computer_algebra_system" rel="nofollow">CAS</a>) while
  keeping the code as simple as possible in order to be comprehensible
  and easily extensible. SymPy is written entirely in Python.</p>
</blockquote>

<p>With sympy, you could solve your problem like this:</p>

<pre><code>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, "--&gt;", s2
</code></pre>

<p>Output:</p>

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

<p>zoo means "complex infinity". For more info, read the <a href="http://docs.sympy.org/latest/tutorial/basic_operations.html" rel="nofollow">docs</a>. </p>

<p>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 <a href="http://www.sympy.org/en/index.html" rel="nofollow">sympy</a> though.</p>

python python-2.7