如何使用 Python(Sympy) 实现一个函数,实现与 Wolfram Mathematica 中的'_'和替换规则相同的函数?



在Wolfram Mathematica中,我可以定义_(称为Blank(与任何表达式匹配的命名模式,然后在替换规则中使用匹配。

一个例子:

testexpr = p1[MM]*p2[NN] + p1[XX]*p2[MM] + p1[XX]^2;
FunTest[expr_] := Expand[expr] /. {(p1[l1_]*p2[l2_]) -> FF1[l1]*FF2[l2], 
p1[l1_]^n_ -> 0, p2[l1_]^n_ -> 0}
FunTest[testexpr]

结果是FF1[XX] FF2[MM] + FF1[MM] FF2[NN]

然而,我不知道如何在Python中使用sympy来做同样的事情。

import sympy as sp
p1 = sp.IndexedBase("p1")
p2 = sp.IndexedBase("p2")
FF1 = sp.IndexedBase("FF1")
FF2 = sp.IndexedBase("FF2")
MM,NN,XX=sp.symbols('MM NN XX')
SSlist=[MM,NN,XX]
testexpr=p1[MM]*p2[NN] + p1[XX]*p2[MM] + p1[XX]**2 
def FunTest(expr): 
expr=expr.subs([(p1[SS]*p2[SS2],FF1[SS]*FF2[SS2]) for SS in SSlist 
for SS2 in SSlist]+[(p1[SS]**2,0) for SS in SSlist]+[(p2[SS]**2,0) 
for SS in SSlist],simultaneous=True)
return expr
rest=FunTest(testexpr) 
print(rest)   

因此结果也是CCD_ 3。

但我想知道是否有一种简单的方法可以让它更通用,比如Wolfram Mathematica。如果SSlist是一个大列表,并且有许多不同的变量,那么使用我的解决方案将很难实现。

我想知道是否有一种简单的方法可以不在整个列表上写循环,对于SSlist中的SS,就像在Mathematica中一样。熟悉症状的人能给我一些提示吗?

非常感谢!

我找到了一个解决我自己问题的方法。结果如我所愿。我没有使用subs((,而是使用了wild运算符和replace((。

import sympy as sp
p1 = sp.IndexedBase("p1")
p2 = sp.IndexedBase("p2")
FF1 = sp.IndexedBase("FF1")
FF2 = sp.IndexedBase("FF2")
MM,NN,XX=sp.symbols('MM NN XX')
SSlist=[MM,NN,XX]
SS = sp.Wild('SS')
SS1 = sp.Wild('SS1')
testexpr=p1[MM]*p2[NN] + p1[XX]*p2[MM] + p1[XX]**2 
replacements = {p1[SS]*p2[SS1] : FF1[SS]*FF2[SS1], p1[SS]**2: 0, p2[SS]**2 : 0}
def replaceall(expr, repls):
for i, j in repls.items():
expr = expr.replace(i, j, map=False, simultaneous=True, exact=False)   
return expr
rest=replaceall(testexpr,replacements) 
print(rest)

结果和我以前做的完全一样:

FF1[MM]*FF2[NN] + FF1[XX]*FF2[MM]

我想知道的一件事是,当因为for循环而有很多符号时,这种效率是很高的。这两种方法似乎很相似,只是我最近发现的方法看起来更简洁。

我想知道是否有像Wolfram Mathematica那样更通用的方法来做这些事情。

欢迎任何意见。谢谢

最新更新