# Sympy substituting many variables with powers

## Question:

Really, this is two questions in one.

Suppose I have the following code:

``````from sympy import *

x1, x2, x3, y1, y2, y3 = symbols("x1 x2 x3 y1 y2 y3")

term = x1**5 + (x2**2)*(x3**3) + x1**4 + x1**3 + x1**2 + x1

term = term.subs(x1**2, y1)
term = term.subs(x2**2, y2)
term = term.subs(x3**2, y3)
``````

After the above, `term` takes the value `x1**5 + x1**3 + x1 + x3**3*y2 + y1**2 + y1`.

Question 1: I would like to turn all x_i^(2n+1) into the form x_i*(y_i^n) – but this leaves the odd powers of x_i alone. Is there any way to achieve this?

Question 2: Is there a way of typing something like `term = term.subs(xi**2, yi)`, rather than rewriting the substitution for each x_i?

Something like this seems to work. Just be aware of the difference in the index base.

``````from sympy import *

x = symbols("x1 x2 x3")
y = symbols("y1 y2 y3")

term = x**5 + (x**2)*(x**3) + x**4 + x**3 + x**2 + x
for i in range(3):
term = term.subs(x[i]**2, y[i])
for n in range(3):
term = term.subs(x[i]**(2*n+1), x[i]*y[i]**n)
term
`````` You can just tell the `replace` method to find powers with odd exponents and replace them as you described in the OP. The `sym` lambda is a function to give a new symbol to use for the odd case. In the first example  I use the integer attribute to create a new symbol that looks like the one appearing in the power but behaving distinctly (since symbols are known by their attributes). In the second example, I assume that only the first letter is going to be replaced with `y` (like you had said).

Since the replace does not care about the name of the variables, there is no need for an explicit loop to check all bases.

Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.