Plugging in numbers and getting a decimal answer is the bridge from a derived formula to a usable result.
expr.subs(old, new) returns a new expression with old replaced. new can be a number or any expression, so substitution also composes formulas. Pass a dict or list of pairs to replace several symbols at once: expr.subs({x: 2, y: 1}). The original expression is unchanged, because expressions are immutable.
Substituting numbers gives an exact result when the numbers are exact: sqrt(x).subs(x, 8) is 2*sqrt(2), not 2.828.... To get a decimal, call evalf() (or the function N()). Both take a number of significant digits: pi.evalf(50). SymPy evaluates with arbitrary precision (via mpmath), so asking for 50 digits really gives 50 correct digits.
For evaluating at a numeric point, expr.evalf(subs={x: 1.5}) is better than expr.subs(x, 1.5).evalf(): it substitutes during numeric evaluation, which avoids building a large intermediate exact expression and can be more accurate.
Substitution is also about structure. subs is mathematically aware: (x**4).subs(x**2, y) gives y**2. If you want a purely literal replacement of exact subtrees, xreplace does that (covered later).
Evaluating a formula at thousands of points with subs and evalf is slow, because each call walks the tree. For bulk numeric work, convert the expression to a NumPy function with lambdify.
Example
from sympy import symbols, sqrt, pi, N
x, y = symbols("x y")
expr = x**2 + y
print(expr.subs(x, 3)) # y + 9
print(expr.subs({x: 2, y: 1})) # 5
print(expr.subs(x, y + 1)) # y + (y + 1)**2
print((x**4).subs(x**2, y)) # y**2
print(sqrt(x).subs(x, 8)) # 2*sqrt(2)
print(sqrt(8).evalf()) # 2.82842712474619
print(N(pi, 20)) # 3.1415926535897932385
print(expr.evalf(subs={x: 1.5, y: 0})) # 2.25000000000000
print(expr) # x**2 + y (unchanged)Remember
- subs returns a new expression; pass a dict for several symbols
- evalf(n) / N(expr, n) give n significant digits
- Use evalf(subs=...) for numeric points and lambdify for many points
Watch out for
- Expecting expr.subs(...) to modify expr in place: assign the result.