В 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
также автоматически преобразует любые неопределенные переменные в выражении в символ или функцию, тогда как eval
этого не делает.sympify
автоматически оценивает выражение в пространстве имен SymPy, поэтому любая функция SymPy будет определена автоматически (с eval
вам нужно либо импортировать имя вручную, либо добавить его в словарь в качестве второго аргумента)sympify
может стать лучше eval
с точки зрения безопасности (см. https://github.com/sympy/sympy/pull/12524). На данный момент оба могут выполнять произвольный код, поэтому их небезопасно использовать для ненадежного ввода.Производительность любого из них должна быть незначительной. Поэтому я бы рекомендовал использовать sympify
, а не eval
для создания выражений SymPy.
@XuemeiGu Я отредактировал свой ответ, указав различия между sympify
и eval
.
Спасибо большое. Я нашел другой способ сделать это, просто используя eval(). Честно говоря, я не знаю, что быстрее или они одинаковы.