Wolfram mathematica 使用带纯函数的Evaluate和SetDelayed

Wolfram mathematica 使用带纯函数的Evaluate和SetDelayed,wolfram-mathematica,Wolfram Mathematica,我想通过将列表传递给某个函数来计算下面的f: f = {z[1] z[2], z[2]^2}; a = % /. {z[1]-> #1,z[2]-> #2}; F[Z_] := Evaluate[a] & @@ Z ; 所以现在如果我尝试F[{1,2}]我得到了{2,4}。但仔细观察,F将返回定义 F[Z_] := (Evaluate[a] &) @@ Z 这取决于a的值,因此如果我们设置a=3,然后计算F[{1,2}],我们得到3。我知道添加最后一个&会使评估

我想通过将列表传递给某个函数来计算下面的f:

f = {z[1] z[2], z[2]^2};
a = % /. {z[1]-> #1,z[2]-> #2};
F[Z_] := Evaluate[a] & @@ Z ; 
所以现在如果我尝试
F[{1,2}]
我得到了
{2,4}
。但仔细观察,F将返回定义

F[Z_] := (Evaluate[a] &) @@ Z
这取决于
a
的值,因此如果我们设置
a=3
,然后计算
F[{1,2}]
,我们得到
3
。我知道添加最后一个
&
会使
评估[a]
保持不变,但是什么是优雅的解决方法呢?本质上,我需要强制对
Evaluate[a]
进行评估,主要是为了提高效率,因为
a
实际上相当复杂

请有人帮忙,并考虑到
f
必须包含一个
数组[z,2]
,该数组由一些未知的计算给出。这么写

F[Z_] := {Z[[1]]Z[[2]],Z[[2]]^2}
这还不够,我需要从我们的
f
自动生成这个


非常感谢您的贡献
您可以将
a
的值注入
函数
SetDelayed
的主体中,使用

With[{body = a},
 F[Z_] := body & @@ Z
]
检查定义:

Definition[F]
您会注意到,由于嵌套的作用域构造,
Z
已变成
Z$
,但行为是相同的


你在评论中说:

如果
z[i]
的值被更改,那么这种解决方法就会失败,这再次让我感到困扰

虽然在上述定义了
F[Z_]
之后,这应该不是问题,但如果您希望保护对
a
所做的替换,可以使用正式符号,而不是
Z
。这些是用Esc
$z
Esc输入的,例如,对于正式的z。形式符号具有受保护的属性,并专门存在以避免此类冲突

这在笔记本中看起来比在这里好得多:

f = {\[FormalZ][1] \[FormalZ][2], \[FormalZ][2]^2};
a = f /. {\[FormalZ][1] -> #1, \[FormalZ][2] -> #2};
另一种方法是在
Hold
表达式中进行替换,并通过使用
Unevaluated
,保护规则本身不被计算:

ClearAll[f, z, a, F, Z]

z[2] = "Fail!";

f = Hold[{z[1] z[2], z[2]^2}];
a = f /. Unevaluated[{z[1] -> #1, z[2] -> #2}] // ReleaseHold;

With[{body = a},
 F[Z_] := body & @@ Z
]

Definition[F]

“自然”的方式似乎将一切都作为参数传递给F[z_,fa_,fa_](具有方便的定义)。有什么理由不这样做吗?你的意思是像
F[Z,F][1]:=(F/{Z[1]->1,Z[2]->2})和@Z
?这是可行的,但我认为这是一个低效的解决方案,因为有些东西需要使用数万次。如果
z[i]
的值被更改,那么这种解决方法就会失败,这再次让我感到困扰。谢谢你的评论。太好了,谢谢。我也适当地注意到了Mathematica的专用站点。我现在就实施!
ClearAll[f, z, a, F, Z]

z[2] = "Fail!";

f = Hold[{z[1] z[2], z[2]^2}];
a = f /. Unevaluated[{z[1] -> #1, z[2] -> #2}] // ReleaseHold;

With[{body = a},
 F[Z_] := body & @@ Z
]

Definition[F]
F[Z$_] := ({#1 #2, #2^2} &) @@ Z$