A light-weight question for the experts. I can't seem to figure the correct syntax to this replacement. I have this list
Clear[a, b, c, d]
polesList = {{3, {a, b}}, {5, {c, d}}};
It is of the form of a list with sublists each have the form {order,{x,y}} and I want to generate a new list of this form (x+y)^order
Currently this is what I do, which works:
((#[[2, 1]] + #[[2, 2]])^#[[1]]) & /@ polesList
(* -----> {(a + b)^3, (c + d)^5} *)
But I have been trying to learn to use ReplaceAll
as it is more clear to me than pure functions, since I can see the pattern better, like this:
Clear[a, b, c, d, n]
polesList = {{3, {a, b}}, {5, {c, d}}};
ReplaceAll[polesList, {n_, {x_, y_}} :> (x + y)^n] (*I thought this will work*)
I get strange result, which is
{(5 + c)^3, {(5 + d)^a, (5 + d)^b}}
What is the correct syntax to do this replacement using ReplaceAll
instead of the pure function method?
Thanks
Update:
I find that using Replace, instead of ReplaceAll
works, but need to say {1} at the end:
Clear[a, b, c, d, n]
polesList = {{3, {a, b}}, {5, {c, d}}};
Replace[polesList, {n_, {x_, y_}} :> (x + y)^n, {1}]
which gives
{(a + b)^3, (c + d)^5}
But ReplaceAll
does not take {1} at the end. I am more confused now which to use :)
The problem is that ReplaceAll
inspects all levels of the expression when looking for replacements. The entire expression matches the pattern {n_, {x_, y_}}
where:
n
matches {3, {a, b}}
x
matches 5
y
matches {c, d}
So you end up with (5 + {c , d}) ^ {3, {a, b}}
which evaluates to the result you see.
There are a few ways to fix this. First, you can change the pattern so that it does not match the outermost list. For example, if the n
values are always integers you could use:
ReplaceAll[polesList, {n_Integer, {x_, y_}} :> (x + y)^n]
Or, you could use Replace
instead of ReplaceAll
, and restrict the pattern matching the first level only:
Replace[polesList, {n_, {x_, y_}} :> (x + y)^n, {1}]
I find that applying replacement rules to the first level of a list is very common. It so happens that Cases
, by default, only operates on that level. So I find myself frequently using Cases
for level one replacements when I know that all elements will match the pattern:
Cases[polesList, {n_, {x_, y_}} :> (x + y)^n]
This last expression is how I would probably write the desired replacement. Keep in mind, though, that if all elements do not match the pattern, then the Cases
approach will drop the mismatches from the result.
The problem is that ReplaceAll
looks at all levels in the expression and the first match to the pattern
{n_, {x_, y_}}
in the expression {{3, {a, b}}, {5, {c, d}}}
is
{ n=={3, {a, b}}, {x==5, y=={c, d}}}
(if that notation is clear)
So you got the "strange" result
(5 + {c,d})^{3, {a, b}} == {5+c, 5+d}^{3, {a, b}}
== {(5+c)^3, (5+d)^{a, b}} == {(5+c)^3, {(5+d)^a,(5+d)^b}}
The easiest fix, if n
is always numeric, is
In[2]:= {{3, {a, b}}, {5, {c, d}}} /. {n_?NumericQ, {x_, y_}} :> (x + y)^n
Out[2]= {(a + b)^3, (c + d)^5}
Where I used the shorthand /.
for ReplaceAll
.
It might be that using Replace
at level 1 is the best option
In[3]:= Replace[{{3, {a, b}}, {5, {c, d}}}, {n_,{x_,y_}}:>(x+y)^n, {1}]
Out[3]= {(a+b)^3,(c+d)^5}
which should be compared with the default replace that works at the top level {0}
In[4]:= Replace[{{3, {a, b}}, {5, {c, d}}}, {n_,{x_,y_}}:>(x+y)^n]
Out[4]= {(5+c)^3,{(5+d)^a,(5+d)^b}}
You could also use ReplaceAll[ ]
with Map:
Map[ReplaceAll[#, {n_, {x_, y_}} :> (x + y)^n] &, polesList]
or (using shorthands increasingly)
ReplaceAll[#, {n_, {x_, y_}} :> (x + y)^n] & /@ polesList
or
# /. {n_, {x_, y_}} :> (x + y)^n & /@ polesList
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With