如果我在 Mathematica 中执行以下操作
f[l_] := Module[{}, l[[1]] = Append[l[[1]], 3]; l]
f[{{}, 3}]
我得到一个错误:
Set::setps: "{{},3} in the part assignment is not a symbol. "
甚至 l={{}, 3};f[l]
也会出现同样的错误。但我可以做 f[l_] := Module[{}, {Append[l[[1]], 3],l[[2]]}]
或 l = { {}, 3}; l[[1]] = 追加[l[[1]], 3];我
.
你的解释是什么?
最佳答案
这里有多个问题:
正尝试对非符号分配零件,正如错误消息所述。
尝试像操作符号一样操作命名替换对象。
在此构造中发生的替换:
f[x_] := head[x, 2, 3]
类似于With
:
With[{x = something}, head[x, 2, 3]]
也就是说,替换是在评估之前直接进行的,这样函数 Head
甚至不会看到对象 x
。看看会发生什么:
ClearAll[f,x]
x = 5;
f[x_] := (x = x+2; x)
f[x]
During evaluation of In[8]:= Set::setraw: Cannot assign to raw object 5. >> Out[]= 5
This evaluates as: (5 = 5+2; 5)
so not only is assignment to 5
impossible, but all instances of x
that appear in the right hand side of :=
are replaced with the value of x when it is fed to f
. Consider what happens if we try to bypass the assignment problem by using a function with side effects:
ClearAll[f, x, incrementX]
incrementX[] := (x += 2)
x = 3;
incrementX[];
x
5
So our incrementX
function is working. But now we try:
f[x_] := (incrementX[]; x)
f[x]
5
incrementX
did not fail:
x
7
Rather, the the value of x
was 5
at the time of evaluation of f[x]
and therefore that is returned.
What does work?
What options do we have for things related to what you are attempting? There are several.
1. Use a Hold attribute
We can set a Hold attribute such as HoldFirst
or HoldAll
on the function, so that we may pass the symbol name to RHS functions, rather than only its value.
ClearAll[heldF]
SetAttributes[heldF, HoldAll]
x = {1, 2, 3};
heldF[x_] := (x[[1]] = 7; x)
heldF[x]
x
<pre>{7, 2, 3}</pre>
<pre>{7, 2, 3}</pre>
我们看到 x
的全局值和 heldF
返回的 x
表达式都发生了变化。请注意,必须为 heldF
提供一个 Symbol 作为参数,否则您将再次尝试 {1, 2, 3}[[1]] = 7
。
2。使用临时符号
正如 Arnoud Buzing 所示,我们还可以在 Module
中使用临时 Symbol。
ClearAll[proxyF]
x = {1, 2, 3};
proxyF[x_] := Module[{proxy = x}, proxy[[1]] = 7; proxy]
proxyF[x]
proxyF[{1, 2, 3}]
x
{7, 2, 3}
{7, 2, 3}
{1, 2, 3}
3. Use ReplacePart
We can also avoid symbols completely and just use ReplacePart
:
ClearAll[directF]
x = {1, 2, 3};
directF[x_] := ReplacePart[x, 1 -> 7]
directF[x]
x
{7, 2, 3}
{1, 2, 3}
This can be used for modifications rather than outright replacements as well:
ClearAll[f]
f[l_] := ReplacePart[l, 1 :> l[[1]] ~Append~ 3]
f[{{}, 3}]
{{3}, 3}
关于wolfram-mathematica - 了解 Mathematica 中的模块参数修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8218294/