了解 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];升。
你的解释是什么?
If I do the following in Mathematica
f[l_] := Module[{}, l[[1]] = Append[l[[1]], 3]; l]
f[{{}, 3}]
I get an error:
Set::setps: "{{},3} in the part assignment is not a symbol. "
Even l={{}, 3};f[l]
gets the same error. But I can do f[l_] := Module[{}, {Append[l[[1]], 3],l[[2]]}]
or l = {{}, 3}; l[[1]] = Append[l[[1]], 3]; l
.
What is your explanation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这里存在多个问题:
尝试对非符号进行部件分配,正如错误消息所述。
尝试像操作符号一样操作命名替换对象。
此结构中发生的替换:
与
With
类似:也就是说,替换是在求值之前直接进行的,这样函数
Head
甚至永远不会看到一个对象x
。看看会发生什么:它的计算结果为:
(5 = 5+2; 5)
,因此不仅不可能分配给5
,而且x 的所有实例都不可能分配
在输入到:=
右侧出现的f
时被替换为 x 的值。考虑一下如果我们尝试使用有副作用的函数来绕过赋值问题会发生什么:所以我们的incrementX函数正在工作。但现在我们尝试:
incrementX
没有失败:相反,在计算
f 时,
,因此被返回。x
的值为5
[x]有什么作用?
对于与您正在尝试的事情相关的事情,我们有哪些选择?有好几个。
1. 使用 Hold 属性
我们可以在函数上设置一个 Hold 属性,例如
HoldFirst
或HoldAll
,这样我们就可以将符号名称传递给 RHS 函数,而不仅仅是传递符号名称它的价值。我们看到
x
的全局值和heldF
返回的x
表达式都发生了变化。请注意,必须为heldF
提供一个 Symbol 作为参数,否则您将再次尝试{1, 2, 3}[[1]] = 7
。2. 使用临时符号
正如 Arnoud Buzing 所示,我们还可以在
Module
中使用临时符号。3. 使用 ReplacePart
我们还可以完全避免符号,只使用
ReplacePart
:这可以用于修改,而不是直接替换:
There are multiple problems here:
Attempting Part assignment on a non-Symbol, just as the error message states.
Attempting to manipulate a named replacement object as though it were a symbol.
The replacement that takes place in this construct:
Is analogous to that of
With
:That is, the substitution is made directly and before evaluation, such that the function
Head
never even sees an objectx
. Look what happens with this:This evaluates as:
(5 = 5+2; 5)
so not only is assignment to5
impossible, but all instances ofx
that appear in the right hand side of:=
are replaced with the value of x when it is fed tof
. Consider what happens if we try to bypass the assignment problem by using a function with side effects:So our
incrementX
function is working. But now we try:incrementX
did not fail:Rather, the the value of
x
was5
at the time of evaluation off[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
orHoldAll
on the function, so that we may pass the symbol name to RHS functions, rather than only its value.We see that both the global value of
x
, and thex
expression returned byheldF
are changed. Note thatheldF
must be given a Symbol as an argument otherwise you are again attempting{1, 2, 3}[[1]] = 7
.2. Use a temporary Symbol
As Arnoud Buzing shows, we can also use a temporary Symbol in
Module
.3. Use ReplacePart
We can also avoid symbols completely and just use
ReplacePart
:This can be used for modifications rather than outright replacements as well:
尝试
一下,您会发现
l
的值在求值之前被插入到l[[1]] = Append[l[[1]], 3]
位中。所以 mma 正在尝试评估这个:{{}, 3}[[1]] = {3}
这可能会做你想要的事情
(想法是避免分配给
的部分l
,因为l
将在尝试分配之前进行评估)Try
and you see that the value of
l
is inserted into thel[[1]] = Append[l[[1]], 3]
bit before evaluation. So mma is attempting to evaluate this:{{}, 3}[[1]] = {3}
This may do something like you want
(the idea is to avoid assigning to parts of
l
, sincel
will be evaluated before the assignment is attempted)如果您确实想在模块中使用 Part,您可能需要考虑使用临时变量:
并且:
If you do want to use Part in your Module, you may want to consider using a temporary variable:
And: