In Wolfram Mathematica, I can define named patterns where _ (called Blank) matches any expression and then use the match in a replacement rule.
An example:
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]
The result is FF1[XX] FF2[MM] + FF1[MM] FF2[NN]
However, I don't know how to use sympy in Python to do the same thing.
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)
So the result is also FF1[MM]*FF2[NN] + FF1[XX]*FF2[MM].
But I want to know if there is an easy way to make it more general, as in Wolfram Mathematica. If SSlist is a large list and there are many different variables, it will be a difficult to implement with my solution.
I wonder whether there is an easy way without writing a loop over the whole list, for SS in SSlist, as in Mathematica. Can someone familiar with sympy give me any hints?
Thanks a lot!