# How to replace all elements of a list by a rule "element" -> "element_"

I have a list:

{a, b, c, d, e, f, g, h, i, j}


The goal is to get:

{a_, b_, c_, d_, e_, f_, g_, h_, i_, j_}


I can replace one particular element by using:

{a, b, c, d, e, f, g, h, i, j} /. a -> a_


But my attemps to expand this approach to all elements doesn't work. What can I do?

• {a, b, c, d, e, f, g, h, i, j} _ /. Times -> Pattern, which "accidentally" works since Times is Orderless and Blank[] happens to come after the variables. Dec 17 '19 at 22:10
• @MichaelE2 Sneaky... I like it! Actually I think you should put that in your answer; it's really fun. Dec 17 '19 at 22:19
• @Mr.Wizard OK, done. Thanks, Dec 17 '19 at 22:27
• Related: (121845) Jan 29 '20 at 12:57

Here is one way:

Pattern[#, Blank[]] & /@ {a, b, c, d, e, f, g, h, i, j}
(* {a_, b_, c_, d_, e_, f_, g_, h_, i_, j_} *)


An inspection of the FullForm of a_ reveals why this works:

a_ // FullForm
(* Pattern[a, Blank[]] *)


We can abbreviate slightly if we realize that the InputForm of Blank[] is _:

Pattern[#, _] & /@ {a, b, c, d, e, f, g, h, i, j}
(* {a_, b_, c_, d_, e_, f_, g_, h_, i_, j_} *)


As an alternative approach, one might think to use pattern-matching replacement instead:

Replace[{a, b, c, d, e, f, g, h, i, j}, s_Symbol :> s_, {1}]
(*
RuleDelayed::rhs: Pattern s_ appears on the right-hand side of rule s_Symbol:>s_.
{a_, b_, c_, d_, e_, f_, g_, h_, i_, j_}
*)


... but Mathematica issues a warning because most of the time having a pattern on the right-hand side of a rule is a mistake. In this particular case it is not an error, so we have to use Quiet to tell Mathematica that:

Quiet[Replace[{a, b, c, d, e, f, g, h, i, j}, s_Symbol :> s_, {1}], RuleDelayed::rhs]
(* {a_, b_, c_, d_, e_, f_, g_, h_, i_, j_} *)

• One could also seize the opportunity to write the first one with the new OperatorApplied[Pattern][_] /@ {a, b, c, d, e, f, g, h, i, j}.
– Rojo
May 10 '20 at 22:31

A few additional alternatives to inject patterns on the rhs:

list = {a, b, c, d, e, f, g, h, i, j};

Replace[list, a_ :> (x_ /. x -> a), 1]


{a_, b_, c_, d_, e_, f_, g_, h_, i_, j_}

Replace[list, a_ :> (Pattern[#, _] &@a), 1]


{a_, b_, c_, d_, e_, f_, g_, h_, i_, j_}

Activate @ Replace[list, a_ :> Inactive[Pattern][a, _], 1]


{a_, b_, c_, d_, e_, f_, g_, h_, i_, j_}

Replace[list, a_ :> foo[a, _], 1] /. foo -> Pattern


{a_, b_, c_, d_, e_, f_, g_, h_, i_, j_}

convert it to string and then deal with it

ToExpression@StringJoin[#,"_"]&/@ToString/@{a,b,c,d,e}


a shorter way

ToExpression@StringJoin[ToString@#,"_"]&/@{a,b,c,d,e}


Here is a (silly?) way

Insert[Pattern/@#,Blank[],{#,2}&/@Range@Length@#]&@{a,b}

{a_,b_}


It works with held expressions

a=1;
b=2;
Insert[Pattern/@#,Blank[],{#,2}&/@Range@Length@#]&@Hold[a,b]

Hold[a_,b_]


The following is the silliest I could make it

#/.a_-> ReplacePart[#0[[1,2,1]],1-> #]&/@{a,b,c}

{a_,b_,c_}


Another alternative:

Function[x, x_, Listable][{a, b, c, d, e, f, g, h, i, j}]
(*  {a_, b_, c_, d_, e_, f_, g_, h_, i_, j_}  *)


Playful alternatives: These work "accidentally", since Times is Orderless and Blank[] happens to come after the variables.

{a, b, c, d, e, f, g, h, i, j} _ /. Times -> Pattern
Pattern @@@ ({a, b, c, d, e, f, g, h, i, j} _)

• Very nice! One I'll try to remember. Dec 17 '19 at 22:14

Other options to avoid the warning message:

With[{a = #}, a_] & /@ {a, b, c, d, e, f, g, h, i, j}

Pattern[{a, b, c, d, e, f, g, h, i, j}, _] // Thread


Or to suppress it:

Cases[{a, b, c, d, e, f, g, h, i, j}, a_ :> a_] // Quiet


Yet another way to do it (triggering a warning along the way)

{a, b, c, d, e, f, g, h, i, j} /. u_Symbol /; Context[u] == "Global" :> u_


I had not realised you could use Context` in pattern matching.