wolfram-mathematica - 了解 Mathematica 中的模块参数修改

标签 wolfram-mathematica

如果我在 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];我.

你的解释是什么?

最佳答案

这里有多个问题:

  1. 正尝试对非符号分配零件,正如错误消息所述。

  2. 尝试像操作符号一样操作命名替换对象。

在此构造中发生的替换:

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/

相关文章:

wolfram-mathematica - 三个矩阵的乘积最终是一个奇数 block 矩阵?

excel - 电力运营商不一致

command-line - 从命令行使用命令行args,stdin,stdout和stderr调用Mathematica程序

c++ - 数学问题 : Triangle, 金字塔、旋转、平移、缩放

wolfram-mathematica - 查找和转换HTML文件并在网上移动它们

plot - 平滑密度图 Mathematica

wolfram-mathematica - 想要一种简单快速的方法来延长 3D 绘图的刻度

wolfram-mathematica - 我想将 f^2 定义为 1 但保留 f 未定义

wolfram-mathematica - 使用 Mathematica 识别时间序列中的重要最小值和最大值

vector - 从离散向量场提取积分曲线(Mathematica)