我有以下问题.
f[1]=1;
f[2]=2;
f[_]:=0;
dvs = DownValues[f];
Run Code Online (Sandbox Code Playgroud)
这给了
dvs =
{
HoldPattern[f[1]] :> 1,
HoldPattern[f[2]] :> 2,
HoldPattern[f[_]] :> 0
}
Run Code Online (Sandbox Code Playgroud)
我的问题是我想只提取f [1]和f [2]等的定义,而不是一般定义f [_],我不知道如何做到这一点.
我试过了,
Cases[dvs, HoldPattern[ f[_Integer] :> _ ]] (*)
Run Code Online (Sandbox Code Playgroud)
但它没有给我什么,即空列表.
有趣的是,将HoldPattern更改为临时^脚注
dvs1 = {temporary[1] :> 1, temporary[2] :> 2, temporary[_] :> 0}
Run Code Online (Sandbox Code Playgroud)
发行
Cases[dvs1, HoldPattern[temporary[_Integer] :> _]]
Run Code Online (Sandbox Code Playgroud)
给
{temporary[1] :> 1, temporary[2] :> 2}
Run Code Online (Sandbox Code Playgroud)
它的工作原理.这意味着(*)几乎是一种解决方案.
我不明白为什么它适用于临时而不是HoldPattern?如何使用HoldPattern直接使其工作?
当然,问题是什么得到评估,什么不得等.在Mathematica编码时的以太问题.对于真正的大师来说......
最好的问候佐兰
脚注=我手动输入它作为替换"/ .HoldPattern - > temporary"实际上执行f [_]:= 0规则并给出一些奇怪的,我当然希望避免这种情况.
原因是你必须逃避HoldPattern,或许用Verbatim:
In[11]:= Cases[dvs,
Verbatim[RuleDelayed][
Verbatim[HoldPattern][HoldPattern[f[_Integer]]], _]]
Out[11]= {HoldPattern[f[1]] :> 1, HoldPattern[f[2]] :> 2}
Run Code Online (Sandbox Code Playgroud)
只有少数头是必要的,并且HoldPattern是其中之一,正是因为它通常对模式匹配器是"不可见的".对于您temporary或其他负责人来说,没有必要这样做.请注意图案f[_Integer]的包装方式HoldPattern- 此时间HoldPattern用于直接目的 - 保护图案免受评估.请注意,RuleDelayed它也包含在内- 这Verbatim实际上是另一种常见情况Verbatim- 这是必需的,因为它Cases有一个涉及规则的语法,我们不想Cases在这里使用这种解释.所以,这是IMO一个非常好的例子来说明HoldPattern和Verbatim.另请注意,完全可以实现目标HoldPattern,如下所示:
In[14]:= Cases[dvs,HoldPattern[HoldPattern[HoldPattern][f[_Integer]]:>_]]
Out[14]= {HoldPattern[f[1]]:>1,HoldPattern[f[2]]:>2}
Run Code Online (Sandbox Code Playgroud)
但是,HoldPattern用于逃避目的(代替Verbatim)是IMO在概念上的错误.
编辑
为了稍微调整一下情况Cases,这里有一个简单的例子,我们使用Cases涉及转换规则的语法.这种扩展语法Cases不仅指示查找和收集匹配的片段,而且还在它们被找到后立即根据规则对它们进行变换,因此结果列表包含变换后的片段.
In[29]:= ClearAll[a, b, c, d, e, f];
Cases[{a, b, c, d, e, f}, s_Symbol :> s^2]
Out[30]= {a^2, b^2, c^2, d^2, e^2, f^2}
Run Code Online (Sandbox Code Playgroud)
但是,如果我们需要找到自己规则的元素呢?如果我们试试这个:
In[33]:= Cases[{a:>b,c:>d,e:>f},s_Symbol:>_]
Out[33]= {}
Run Code Online (Sandbox Code Playgroud)
它不起作用,因为Cases将第二个参数中的规则解释为使用扩展语法,查找符号并替换它的指令_.由于它默认在级别1上搜索,并且符号在此处的级别2上,因此它什么也没找到.注意:
In[34]:= Cases[{a:>b,c:>d,e:>f},s_Symbol:>_,{2}]
Out[34]= {_,_,_,_,_,_}
Run Code Online (Sandbox Code Playgroud)
无论如何,这不是我们想要的.因此,我们必须强制Cases将第二个参数视为普通模式(简单而非扩展的语法).有几种方法可以做到这一点,但所有这些方法都以某种方式"逃避" RuleDelayed(或Rule):
In[37]:= Cases[{a:>b,c:>d,e:>f},(s_Symbol:>_):>s]
Out[37]= {a,c,e}
In[38]:= Cases[{a:>b,c:>d,e:>f},Verbatim[RuleDelayed][s_Symbol,_]:>s]
Out[38]= {a,c,e}
In[39]:= Cases[{a:>b,c:>d,e:>f},(Rule|RuleDelayed)[s_Symbol,_]:>s]
Out[39]= {a,c,e}
Run Code Online (Sandbox Code Playgroud)
在所有情况下,我们要么避免扩展语法Cases(最后两个例子),要么设法使用它(第一种情况).
| 归档时间: |
|
| 查看次数: |
234 次 |
| 最近记录: |