如何用Python(Sympy)实现一个函数,实现和Wolfram Mathematica中的ToExpression一样?
How to implement a function with Python(Sympy), realizing the same as ToExpression in Wolfram Mathematica?
在 Wolfram Mathematica 中,我可以使用 ToExpression 将字符串转换为表达式,并对表达式求值。
一个例子:
Reflection[expr_, a_] := expr /. a[l_] -> I*a[-l]
StringA = "Reflection[a[0]b[3],b]"
Output=ToExpression[StringA]
结果是ia[0]b[-3]
但是,我不知道如何在 Python(或 Sympy)中实现这样的事情。
import numpy as np
import sympy as sp
a, b, c, d, e, f=map(sp.IndexedBase,['a','b','c','d','e', 'f'])
l1=map(sp.Wild,['l1'])
imagI=sp.I ## equals to Imaginary
def Reflection(expr, p):
expr=imagI*expr.replace(p[l1],p[-l1], map=False, simultaneous=True, exact=False)
return expr
fundict={'Reflection':Reflection}
pdict={'a':a,'b':b,'c':c,'d':d,'e':e,'f':f} ##A dictionary used for connect the string to existed variable
mydict=dict(fundict,**pdict) ## combine two dictionary
StringA ='Reflection(a(0)b(3),b)'
如何实现与ToExpression一样的功能?
更复杂的情况:
Reflection[expr_, a_] := expr /. a[l_] -> I*a[-l]
OAMHolo[expr_, a_, n_] := expr /. a[l_] -> a[l + n]
StringA = "Reflection[OAMHolo[Reflection[a[0]b[3],b],a,3],b]"
Output=ToExpression[StringA]
输出为-a[3]b[3]
对于 python 的情况,我尝试了 exec()、replace() 但这些都不起作用。那么如何在Python中实现这种情况呢?非常感谢你!
sympify
将字符串转换为表达式。要在 sympify
中使用自定义对象,将它们作为字典传递给第二个参数。
这是你的例子(我也修复了一些小错误)
>>> l1 = Wild('l1')
>>> StringA = 'Reflection(a[0]*b[3], b)'
>>> sympify(StringA, mydict)
I*a[0]*b[-3]
关于 sympify
与 eval
,sympify
在内部使用 eval
。它更聪明,
sympify('1/2')
会产生 Rational(1, 2)
而 eval('1/2')
会产生 0.5
。
sympify
还会自动将表达式中任何未定义的变量转换为 Symbol 或 Function,而 eval
则不会。
sympify
自动计算 SymPy 命名空间中的表达式,因此将自动定义任何 SymPy 函数(使用 eval
您必须手动导入名称或将其添加到字典中作为第二个参数)
- 将来
sympify
在安全方面可能会比 eval
更好(参见 https://github.com/sympy/sympy/pull/12524)。目前,两者都可以执行任意代码,因此在不受信任的输入上使用它们是不安全的。
两者的性能都可以忽略不计。所以我建议使用 sympify
而不是 eval
来创建 SymPy 表达式。
在 Wolfram Mathematica 中,我可以使用 ToExpression 将字符串转换为表达式,并对表达式求值。
一个例子:
Reflection[expr_, a_] := expr /. a[l_] -> I*a[-l]
StringA = "Reflection[a[0]b[3],b]"
Output=ToExpression[StringA]
结果是ia[0]b[-3]
但是,我不知道如何在 Python(或 Sympy)中实现这样的事情。
import numpy as np
import sympy as sp
a, b, c, d, e, f=map(sp.IndexedBase,['a','b','c','d','e', 'f'])
l1=map(sp.Wild,['l1'])
imagI=sp.I ## equals to Imaginary
def Reflection(expr, p):
expr=imagI*expr.replace(p[l1],p[-l1], map=False, simultaneous=True, exact=False)
return expr
fundict={'Reflection':Reflection}
pdict={'a':a,'b':b,'c':c,'d':d,'e':e,'f':f} ##A dictionary used for connect the string to existed variable
mydict=dict(fundict,**pdict) ## combine two dictionary
StringA ='Reflection(a(0)b(3),b)'
如何实现与ToExpression一样的功能?
更复杂的情况:
Reflection[expr_, a_] := expr /. a[l_] -> I*a[-l]
OAMHolo[expr_, a_, n_] := expr /. a[l_] -> a[l + n]
StringA = "Reflection[OAMHolo[Reflection[a[0]b[3],b],a,3],b]"
Output=ToExpression[StringA]
输出为-a[3]b[3]
对于 python 的情况,我尝试了 exec()、replace() 但这些都不起作用。那么如何在Python中实现这种情况呢?非常感谢你!
sympify
将字符串转换为表达式。要在 sympify
中使用自定义对象,将它们作为字典传递给第二个参数。
这是你的例子(我也修复了一些小错误)
>>> l1 = Wild('l1')
>>> StringA = 'Reflection(a[0]*b[3], b)'
>>> sympify(StringA, mydict)
I*a[0]*b[-3]
关于 sympify
与 eval
,sympify
在内部使用 eval
。它更聪明,
sympify('1/2')
会产生Rational(1, 2)
而eval('1/2')
会产生0.5
。sympify
还会自动将表达式中任何未定义的变量转换为 Symbol 或 Function,而eval
则不会。sympify
自动计算 SymPy 命名空间中的表达式,因此将自动定义任何 SymPy 函数(使用eval
您必须手动导入名称或将其添加到字典中作为第二个参数)- 将来
sympify
在安全方面可能会比eval
更好(参见 https://github.com/sympy/sympy/pull/12524)。目前,两者都可以执行任意代码,因此在不受信任的输入上使用它们是不安全的。
两者的性能都可以忽略不计。所以我建议使用 sympify
而不是 eval
来创建 SymPy 表达式。