I have a list of expressions:
{x,x^2,x^3}
and a list of rules
{x->1,x->2,x->3}
How can I get {1,4,27}
by applying the rule to the expression in the corresponding location?
MapThread[ReplaceAll,{{x,x^2,x^3},{x->1,x->2,x->3}}]
{{x, x^2, x^3}, {x -> 1, x -> 2, x -> 3}} // MapThread[ReplaceAll]
$\endgroup$
I would use MapThread
as it is the function designed for this purpose; but here is another solution step by step:
flist = {x, x^2, x^3}
rules = {x -> 1, x -> 2, x -> 3}
Transpose@{flist, rules}
{{x, x -> 1}, {x^2, x -> 2}, {x^3, x -> 3}}
Applying ReplaceAll
to each sublist:
ReplaceAll @@@ Transpose@{flist, rules}
{1, 4, 27}
Not immediately relevant, but you can try the following variations:
x^# /. x -> # & /@ Range[3]
#^# & /@ Range[3]
Array[#^# &, 3]
Table[i^i, {i, 3}]
We define the following lists:
list = {x, x^2, x^3};
rules = {x -> 1, x -> 2, x -> 3};
And then we can run
i[{ii_, iii_}] := ii /. iii;
The following:
Map[i, Transpose@{list, rules}]
and
equivalently
Map[i, Thread@{list, rules}]
Inner[ReplaceAll, list, rules, List]
- Using
Thread
ReplaceAll @@@ Thread[{list, rules}]
- Why not
Table
Table[list[[i]] /. rules[[i]], {i, Length@rules}]
- What on earth are these
@#%^&*?!
fnctn = #1 /. #2 & @@@ Transpose@({##}) &;
fnctn[list, rules]
MapIndexed
served well
MapIndexed[#^# &, Range@Length@list]
Last /@ Power[List @@@ rules, Range[Length@rules]]
While
also works
Module[{return = {}, i = 1, end = Length@list},
While[i <= end,
AppendTo[return, list[[i]] /. rules[[i]]]; i++]; return]
- Using
For
because...why not?
Module[{return = {}}, For[
i = 1, i <= Length@list, i++,
AppendTo[return, list[[i]] /. rules[[i]]]];
return]
- After a lot of trial and error --- see again these weird
@#%^&*?!
stuff
smthng = {#1 /. #4, #2 /. #5, #3 /. #6} & @@ (## & @@@ {##}) &;
smthng[list, rules]
- Something fancier using
GeneralUtilities
Taking from the relevant code from said post, we have:
Needs@"GeneralUtilities`"
Module[{hold},
SetAttributes[hold, HoldAll];
oneTimeRules[rules_] :=
Normal@Merge[rules, ListIterator] /. Rule -> RuleDelayed /.
i_GeneralUtilities`Iterator :>
With[{r = Read[i]}, hold[r, r =!= IteratorExhausted]] /.
hold -> Condition;
];
and then
Replace[list, oneTimeRules@rules, Length@rules]
- Another fancy approach based on
Michael E2's answer
. This serves as a clarifying comment. Grab the relevant code that is needed
SetAttributes[useRepeated, Listable];
useRepeated[(Rule | RuleDelayed)[pat_, repl_], n_ : 1] :=
Module[{used = 0},
pat :> repl /; used++ < n
];
useOnce[r_] := useRepeated[r];
and then use
Replace[list, useOnce@rules, Length@rules]
or equivalently
ReplaceAll[list, useOnce@rules]
Note: if one uses Replace
and the default value of the command -which is set to 1
- the above does not work. So some minor caution is needed.
- Laborious stuff, but works
The following:
(Transpose[{list, Values@rules}] /. {x, i_} -> {i, i} /. {x^2,
i_} :> {i^2, i} /. {x^3, i_} :> {i^3, i})[[All, 1]]
and
equivalently
(Thread[{list, Values@rules}] /. {x, i_} -> {i, i} /. {x^2,
i_} :> {i^2, i} /. {x^3, i_} :> {i^3, i})[[All, 1]]
All of the above give
a = {x, x^2, x^3};
b = {x -> 1, x -> 2, x -> 3};
Two more possibilities:
Diagonal[a /. List /@ b]
{1, 4, 27}
ReplacePart[a, i_ :> (a[[i]] /. b[[i]])]
{1, 4, 27}
list = {x, x^2, x^3};
rules = {x -> 1, x -> 2, x -> 3};
Using SubsetMap
:
SubsetMap[Diagonal@*Function[x, #] &@list, Values@#, Values@#] &@rules
{1, 4, 27}
Or using Outer
:
Diagonal@Outer[ReplaceAll, list, rules]
{1, 4, 27}