如何使用Python(Sympy)实现与Wolfram Mathematica中的ToExpression相同的功能?

时间:2019-04-04 16:22:54

标签: python 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中实现这种情况呢?非常感谢你!

1 个答案:

答案 0 :(得分:1)

sympify将字符串转换为表达式。要在sympify中使用自定义对象,请将它们作为字典传递给第二个参数。

这是您的示例(我还修复了一些小错误)

>>> l1 = Wild('l1')
>>> StringA = 'Reflection(a[0]*b[3], b)'
>>> sympify(StringA, mydict)
I*a[0]*b[-3]

关于sympifyevalsympify在内部使用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表达式。