# How to make expression-dependent replacements?

Consider as a toy example that I want a replacement which acts on

{x,1,2,3}


by replacing $$x$$ with the length of the list itself. In this example this should output

{4,1,2,3}

So I want a code that looks like

{x,1,2,3}/.{x->Length[???]}


where "???" should indicate the expression on which I am doing the replacement. Is there a way to do this or an easy alternative ?

• {x, 1, 2, 3} /. x1 : {x, x2__} :> {Length[x1], x2} Commented Mar 28 at 16:10

You can make a named pattern for the entire list using the : operator:

{x, 1, 2, 3} /. list : {x, rest___} :> {Length[list], rest}

a = {x, 1, 2, 3};


Using SubsetReplace (new in 12.1)

SubsetReplace[a, {x} :> Length[a]]


Using ReplaceAt (new in 13.1)

ReplaceAt[a, _ :> Length[a], 1]


Both produce

{4, 1, 2, 3}

#/.x:>Length[#]&[{x,1,2,3}]

(* {4,1,2,3} *)


Or

Replace[#, x:> Length[#],1]&[{x,1,2,3}]

(* {4,1,2,3} *)


If you can match on the whole expression, you can do this:

{x, 1, 2, 3} /. l : {x, rest___} :> {Length[l], rest}


or

{x, 1, 2, 3} /. l : {x, ___} :> ReplacePart[l, 1 -> Length[l]]


or

{x, 1, 2, 3} /. {x, rest___} :> {1 + Length[{rest}], rest}


For a list of sublists of this type:

biglst = {{x, 1, 2, 3}, {y, 4, 3, 1, 0, 1}, {z, 11, 5}};
{Length[#], Sequence @@ Rest[#]} & /@ biglst

(*  {{4, 1, 2, 3}, {6, 4, 3, 1, 0, 1}, {3, 11, 5}}   *)