Math operations from string [duplicate]

Let's say I have a standard Python string (such as one obtained from raw_input()), maybe "2 + 2" for simplicity's sake.

I'd like to convert this string to standard math operations in Python, such that "2 + 2" would return 4.

Is there an easy way to do this, or would I have to split on the spaces and parse each number/symbol manually, then do the math based on what I find?

Do I want Regex?


Solution 1:

Warning: this way is not a safe way, but is very easy to use. Use it wisely.

Use the eval function.

print eval('2 + 4')

Output:

6

You can even use variables or regular python code.

a = 5
print eval('a + 4')

Output:

9

You also can get return values:

d = eval('4 + 5')
print d

Output:

9

Or call functions:

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

a = 20
b = 10    
print eval('add(a, b)')
print eval('subtract(a, b)')

Output:

30
10

In case you want to write a parser, maybe instead you can built a python code generator if that is easier and use eval to run the code. With eval you can execute any Python evalution.

Why eval is unsafe?

Since you can put literally anything in the eval, e.g. if the input argument is:

os.system(‘rm -rf /’)

It will remove all files on your system (at least on Linux/Unix). So only use eval when you trust the input.

Solution 2:

Regex won't help much. First of all, you will want to take into account the operators precedence, and second, you need to work with parentheses which is impossible with regex.

Depending on what exactly kind of expression you need to parse, you may try either Python AST or (more likely) pyparsing. But, first of all, I'd recommend to read something about syntax analysis in general and the Shunting yard algorithm in particular.

And fight the temptation of using eval, that's not safe.

Solution 3:

You could use this function which is doing the same as the eval() function, but in a simple manner, using a function.

def numeric(equation):
    if '+' in equation:
        y = equation.split('+')
        x = int(y[0])+int(y[1])
    elif '-' in equation:
        y = equation.split('-')
        x = int(y[0])-int(y[1])
    return x