【问题标题】:Evaluating mathematical expressions in Python在 Python 中评估数学表达式
【发布时间】:2011-06-30 06:53:22
【问题描述】:
我想将给定的数学表达式标记为这样的解析树:
((3 + 4 - 1) * 5 + 6 * -7) / 2
'/'
/ \
+ 2
/ \
* *
/ \ / \
- 5 6 -7
/ \
+ 1
/ \
3 4
有没有任何纯 Python 方法可以做到这一点?就像作为字符串传递给 Python,然后像上面提到的那样以树的形式返回。
谢谢。
【问题讨论】:
标签:
python
parsing
math
binary-tree
mathematical-expressions
【解决方案2】:
我不知道执行此操作的“纯 python”方式,它已经为您实现了。但是,您应该查看 ANTLR (http://www.antlr.org/),它是一个开源解析器和词法分析器,它具有适用于多种语言的 API,包括 python。此外,该网站还有一些很棒的视频教程,将向您展示如何按照您的要求进行操作。这是一个非常有用的工具,可以了解如何使用。
【解决方案3】:
是的,Python ast 模块提供了执行此操作的工具。您必须查找您的 Python 版本的确切接口,因为 ast 模块似乎定期更改。
特别是,ast.parse() 方法将对您的应用程序有所帮助:
>>> import ast
>>> ast.parse("(1+2)*3", "", "eval")
<_ast.Expression object at 0x88950>
>>> ast.dump(_)
'Expression(body=BinOp(left=BinOp(left=Num(n=1), op=Add(), right=Num(n=2)), op=Mult(), right=Num(n=3)))'
【解决方案5】:
您可以使用 Python ast 模块来做到这一点。
https://docs.python.org/3.6/library/ast.html
运算是我们要评估的数学运算,我们使用 isinstance 来了解它的类型,如果它是一个数字,如果它是一个二元运算符(+,*,..)。您可以在 https://greentreesnakes.readthedocs.io/en/latest/tofrom.html 阅读 ast 的工作原理
为了使我们可以使用的方法工作:evaluate(ast.parse(theoperation, mode='eval').body)
def evaluate(theoperation):
if (isinstance(theoperation, ast.Num)):
return theoperation.n
if (isinstance(theoperation, ast.BinOp)):
leftope= evaluate(theoperation.left)
rightope=evaluate(theoperation.right)
if (isinstance(theoperation.op, ast.Add)):
return left+right
elif (isinstance(theoperation.op, ast.Sub)):
return left-right
elif (isinstance(theoperation.op, ast.Mult)):
return left*right
elif (isinstance(theoperation.op, ast.Div)):
return left/right
elif (isinstance(theoperation.op, ast.Pow)):
return left**right