列表列表中此ReplaceAll的正确语法是什么?

Nas*_*ser 5 wolfram-mathematica

专家们的轻量级问题.我无法想象这个替换的正确语法.我有这个清单

Clear[a, b, c, d]
polesList = {{3, {a, b}}, {5, {c, d}}};
Run Code Online (Sandbox Code Playgroud)

它是一个列表的形式,子列表每个都有{order,{x,y}}的形式,我想生成这个形式的新列表(x + y)^ order

目前这就是我的工作,它有效:

((#[[2, 1]] + #[[2, 2]])^#[[1]]) & /@ polesList

(* ----->   {(a + b)^3, (c + d)^5}  *)  
Run Code Online (Sandbox Code Playgroud)

但我一直在努力学习使用,ReplaceAll因为它比纯函数更清晰,因为我可以更好地看到模式,如下所示:

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*)
Run Code Online (Sandbox Code Playgroud)

我得到了奇怪的结果,这是

{(5 + c)^3, {(5 + d)^a, (5 + d)^b}}
Run Code Online (Sandbox Code Playgroud)

使用ReplaceAll而不是使用纯函数方法进行此替换的正确语法是什么?

谢谢

更新:

我发现使用Replace而不是ReplaceAllwork,但最后需要说{1}:

Clear[a, b, c, d, n]
polesList = {{3, {a, b}}, {5, {c, d}}};
Replace[polesList, {n_, {x_, y_}} :> (x + y)^n, {1}]
Run Code Online (Sandbox Code Playgroud)

这使

{(a + b)^3, (c + d)^5}
Run Code Online (Sandbox Code Playgroud)

但最后ReplaceAll不需要{1}.我现在更困惑哪个使用:)

Sim*_*mon 8

问题在于ReplaceAll查看表达式中的所有级别以及模式的第一个匹配项

{n_, {x_, y_}}
Run Code Online (Sandbox Code Playgroud)

在表达式{{3, {a, b}}, {5, {c, d}}}

{ n=={3, {a, b}}, {x==5, y=={c, d}}}
Run Code Online (Sandbox Code Playgroud)

(如果该表示法清楚)

所以你得到了"奇怪"的结果

(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}}
Run Code Online (Sandbox Code Playgroud)

最简单的修复,如果n总是数字,则是

In[2]:= {{3, {a, b}}, {5, {c, d}}} /. {n_?NumericQ, {x_, y_}} :> (x + y)^n
Out[2]= {(a + b)^3, (c + d)^5}
Run Code Online (Sandbox Code Playgroud)

我用速记/.的地方ReplaceAll.


可能是Replace在1级使用是最好的选择

In[3]:= Replace[{{3, {a, b}}, {5, {c, d}}}, {n_,{x_,y_}}:>(x+y)^n, {1}]
Out[3]= {(a+b)^3,(c+d)^5}
Run Code Online (Sandbox Code Playgroud)

应该与在顶级工作的默认替换进行比较 {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}}
Run Code Online (Sandbox Code Playgroud)


WRe*_*ach 8

问题是ReplaceAll在查找替换时检查表达式的所有级别.整个表达式匹配模式{n_, {x_, y_}},其中:

n 火柴 {3, {a, b}}

x 火柴 5

y 火柴 {c, d}

所以你最终(5 + {c , d}) ^ {3, {a, b}}评估你看到的结果.

有几种方法可以解决这个问题.首先,您可以更改模式,使其与最外面的列表不匹配.例如,如果n值始终为整数,则可以使用:

ReplaceAll[polesList, {n_Integer, {x_, y_}} :> (x + y)^n]
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用Replace而不是ReplaceAll仅限于匹配第一级的模式:

Replace[polesList, {n_, {x_, y_}} :> (x + y)^n, {1}]
Run Code Online (Sandbox Code Playgroud)

我发现将替换规则应用于列表的第一级非常常见.碰巧的是Cases,默认情况下,只在该级别上运行.因此,Cases当我知道所有元素都与模式匹配时,我发现自己经常使用一级替换:

Cases[polesList, {n_, {x_, y_}} :> (x + y)^n]
Run Code Online (Sandbox Code Playgroud)

最后一个表达式是我可能会编写所需的替换.但请记住,如果所有元素都与模式匹配,那么该Cases方法将从结果中删除不匹配.

  • 带有`:>`的`Cases`为+1.这是一个很好的结构,我在去年才开始使用. (2认同)

Dr.*_*ius 8

您也可以使用ReplaceAll[ ]Map:

Map[ReplaceAll[#, {n_, {x_, y_}} :> (x + y)^n] &, polesList]
Run Code Online (Sandbox Code Playgroud)

或(越来越多地使用短途)

ReplaceAll[#, {n_, {x_, y_}} :> (x + y)^n] & /@ polesList
Run Code Online (Sandbox Code Playgroud)

要么

# /. {n_, {x_, y_}} :> (x + y)^n & /@ polesList
Run Code Online (Sandbox Code Playgroud)