# 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?

## Answers:

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[0]**5 + (x[1]**2)*(x[2]**3) + x[0]**4 + x[0]**3 + x[0]**2 + x[0]
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 [15] 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.