# How to replace all symbols except several?

I'm doing some heavy symbolic calculations and for preliminary simple tests I need to replace all coefficients except chosen with 1, e.g.:

eq = a b c d e f g ...
Replace[eq, Except[a | b] -> 1]


a b ...

Surely that's not working, just illustration. How can I do this?

A little remark: eq/.(c|d|e|f|g|...)->1 will give what I want, but the point is there could be too many coefficients with different names, so it's much easier to write down only the those I want to keep.

• Replace[x^y + a/h - z + k, Except[a | x, _Symbol] -> 1, {0, Infinity}] ? Heads -> False is the default for Replace. Dec 8, 2014 at 16:56
• Oh... thanks a lot. I didn't think about Symbol... Dec 8, 2014 at 17:00
• But I'm not very happy about this solution. For example, Pi is a symbol too and you probably wouldn't want to replace it ... I'd rather make a list of all relevant symbols first and work with that. Just to make sure nothing is included that shouldn't be ... Dec 8, 2014 at 17:02
• In this example this works .. eq /. Cases[ Variables[eq] , v : Except[a | d] :> v -> 1 ] Dec 8, 2014 at 18:13
• as an alternative possibility: Times @@ ToExpression /@ (StringReplace[Map[ToString, List @@ eq], Except[Characters["ab"]] -> "1"]) . Try. Dec 9, 2014 at 12:37

A useful function is Variables[], which returns a list of variables in eq.

eq = a b c d e f g π;

eq /. (Rule[# , 1] & /@ Complement[Variables[eq], {a, b}])

(* a b π *)

• Though Variables[x^a] is {x^a}, not {x,a}. Dec 9, 2014 at 12:11
• Already to be found somewhere on the site as a substitute for Variables: DeleteDuplicates[Cases[eq, _Symbol, -1]] Dec 9, 2014 at 13:44

I dare to post as an answer a very slightly enchanced Szabolcs' comment, which doesn't touch Pi or E and deprived of problems with Variables:

eq = a^(b + b1) c d e Pi E^Pi;
Replace[eq, Except[a | b | _?NumericQ, x_Symbol] -> 1, All]


a^(1 + b) E^Pi Pi

Another way to implement this is as follows:

Create a List of Rules to ReplaceAll Variables with 1:

rules1 = # -> 1 & /@ Variables[eq]
(* {a -> 1, b -> 1, c -> 1, d -> 1, e -> 1, f -> 1, g -> 1, h -> 1, i -> 1, j -> 1, k -> 1, l -> 1, m -> 1, n -> 1, o -> 1, p -> 1, q -> 1, r -> 1, s -> 1, t -> 1, u -> 1, v -> 1, w -> 1, x -> 1, y -> 1, z -> 1} *)


Join to the front of this list of rules a new list with the variables you don't want replaced with 1:

rules2 = Join[{a -> a, b -> b}, # -> 1 & /@ Variables[eq]]
(* {a -> a, b -> b, a -> 1, b -> 1, c -> 1, d -> 1, e -> 1, f -> 1, g -> 1, h -> 1, i -> 1, j -> 1,  k -> 1, l -> 1, m -> 1, n -> 1, o -> 1, p -> 1, q -> 1, r -> 1, s -> 1, t -> 1, u -> 1, v -> 1, w -> 1, x -> 1, y -> 1, z -> 1} *)


Then use ReplaceAll with the new, second list of rules:

eq /. rules2
(* a b *)


You can combine these steps in a single expression, which avoids the creation of unnecessary symbols ("rules1" and "rules2" here):

eq /. Join[{a -> a, b -> b}, # -> 1 & /@ Variables[eq]]
(* a b *)


The following, more robust code works both for the expression eq of the OP as well as for more complicated expressions, such as:

eq2 = a^(b + b1) c d e Pi E^Pi


As one-line code, one can use the following:

eq2 /. Join[{a -> a, b -> b}, # -> 1 & /@ Intersection@Flatten[Cases[#, _?AtomQ, {0, Infinity}] & /@ Variables[eq2]]]
(* a^(1 + b) E^π π *)


This is built up as follows. First, Variables is used, but only on Atoms in the expression. Nested lists are then Flattened and duplicates are removed with Intersection.

varslist = Intersection@Flatten[Cases[#, _?AtomQ, {0, Infinity}] & /@ Variables[eq2]]
(* {a, b, b1, c, d, e} *)


Second, a List of Rules is created to replace all variables in varslist with 1. Then Join to the front of this list of rules a new list with the variables you don't want replaced with 1. Finally, ReplaceAll is used on the expression eq2:

eq2 /. Join[{a -> a, b -> b}, # -> 1 & /@ varslist]
(* a^(1 + b) E^π π *)