如何评估 sympy 中的表达式树?

How to evaluate an expression-tree in sympy?

这可能是一个非常基本的问题,但我想知道在阅读文档后我是否遗漏了一个 sympy 功能,或者这个用例是否真的没有包含。

我有以下表达方式:

a = sympify("b + 5")
b = sympify("c + 5")
c = sympify("5")

我正在尝试评估一个。 sympy 有什么方法可以为您完成所有递归搜索和替换,还是我真的必须手动完成?

如:

eval(str(eval(str(a))))

区分符号和表达式:

import sympy as sy
a, b, c = sy.symbols('a:c')

a_expr = sy.sympify("b + 5")
b_expr = sy.sympify("c + 5")
c_expr = sy.sympify("5")

sy.solve([sy.Eq(a,a_expr), sy.Eq(b,b_expr), sy.Eq(c,c_expr)])

产量

{c: 5, b: 10, a: 15}

上面,a是一个Symbol,但是a_expr是一个表达式:

In [117]: type(a)
Out[117]: sympy.core.symbol.Symbol

In [118]: type(a_expr)
Out[118]: sympy.core.add.Add

给出公式的字典,例如

formulas = {'a': 'b+5', 'b': 'c+5', 'c': '5'}

你可以用 list comprehension

equations = [sy.Eq(sy.symbols(variable), sy.sympify(expr))
             for variable, expr in formulas.items()]

并用

求解方程组
solution = sy.solve(equations)
# {c: 5, b: 10, a: 15}

为什么不应该使用 sympy.var:

处理动态变量时 -- 名称未知的变量,直到 运行-time -- 建议避免使用 sy.varsy.var 添加姓名 全局命名空间的变量。这样做的唯一目的是如果你 将通过名称引用变量。但是根据假设变量 名字在 运行 之前是未知的。所以脚本代码不应该——事实上, 不应该能够 -- 按名称引用变量。因此,如果变量是真正动态的,那么使用 sy.var 应该是无用的。

但这不是真正的问题。动态变量名称(作为字符串) 可以列出

In [22]: formulas.keys()
Out[22]: ['a', 'c', 'b']

并且 sy.Symbols 可以与

一起列出
In [23]: solution.keys()
Out[23]: [c, b, a]

因此您可以编写循环来访问每个变量,而无需定义 每个符号的全局变量名称。