2015-06-21 39 views
0

这可能是一个非常基本的问题,但我想知道在阅读完文档后是否缺少sympy功能,或者如果真的没有包含这个用例。如何评估sympy中的表达式树?

我有以下表述:

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

我试图评估。 有没有什么办法sympy做所有的递归搜索和替换你,或者我真的不得不手动吗?

如:

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

回答

0

使符号和表达之间的区别:

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是一个符号,但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

当动态变量处理 - 变量,其名称是未知的,直到 运行时间 - 最好是避免使用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] 

上市所以,你可以写循环而不必定义 访问每个变量每个符号的全局变量名称。

+0

谢谢!一旦你理解了这个概念,它就变得如此明显。 是否有任何方式以动态方式声明符号(例如,来自列表或长度未知的字典)? – gimili

+0

你的意思是你想要给出一个像[['b + 5','c + 5','5']'这样的列表来声明符号'a','b','c'吗?你知道预先显示在列表中的变量名吗? – unutbu

+0

这个想法是能够计算一个动态系统。鉴于例如字典{'a':'b + 5','b':'c + 5','c':'5'} 有没有为字典的每个条目(键)创建所有符号的方法,而事先不知道字典将会是多久以及密钥将会有哪些名字? – gimili