Set :: setps:在零件赋值中不是符号。 >>

时间:2012-10-13 18:47:07

标签: wolfram-mathematica

我在 Mathematica 中定义了一个函数,其中如果列表中的第i个值为1,并且第i + 1个值为0,则该函数会切换这两个值。 / p>

我把它定义为:

f[i_, x_] := (If[x[[i]] == 1 && x[[i + 1]] == 0, x[[i]] = 1; x[[i + 1]] = 0]);

但是,当我使用i = 2x = {1,1,0,0}对其进行测试时,出现以下错误:

  

零件赋值中的Set :: setps:{1,1,0,0}不是符号。 >>

我不太清楚我做错了什么,因为我以为我正在调用一切。

2 个答案:

答案 0 :(得分:3)

你似乎已经找到了解决方案,但无论如何我们都要打破这个解决方案。

首先,您有一个简单的转录错误,其中Set应用原始值而不是交换它们。通过此更改,基本代码可以正常运行:

i = 2;
x = {1, 1, 0, 0};

If[
 x[[i]] == 1 && x[[i + 1]] == 0,
 x[[i]] = 0; x[[i + 1]] = 1;
]

x
{1, 0, 1, 0}

因此我们成功更改了x。要将此功能转换为函数,我们必须将x名称传递给此代码,而不是x。这是您的错误来源:

{1, 1, 0, 0}[[2]] = 0;
  

零件赋值中的Set :: setps:{1,1,0,0}不是符号。 >>

您需要的是函数的Hold属性:

SetAttributes[f, HoldAll]

f[i_, x_] := If[x[[i]] == 1 && x[[i + 1]] == 0, x[[i]] = 0; x[[i + 1]] = 1;]

i = 2 ;
x = {1, 1, 0, 0};

f[2, x]

x
{1, 0, 1, 0}

也许您并不打算更改x本身的值,但这种技术肯定会在其他应用程序中派上用场。要修改上述函数以操作我们可能使用Module的数据的副本,我们不需要Hold属性:

f2[i_, xImmutable_] :=
  Module[{x = xImmutable},
    If[x[[i]] == 1 && x[[i + 1]] == 0, x[[i]] = 0; x[[i + 1]] = 1];
    x
  ]

i = 2 ;
x = {1, 1, 0, 0};

f2[2, x]
{1, 0, 1, 0}

请注意x中的Module是一个局部变量,而不是您的全局列表x,它保持不变。

为了好玩,让我们以不同的方式实现这一点。

f3[i_, x_] := 
 If[
   x[[i + {0, 1}]] == {1, 0},
   ReplacePart[x, {i -> 0, i + 1 -> 1}],
   x
 ]

f3[2, x]
{1, 0, 1, 0}

答案 1 :(得分:0)

我明白了;我不需要改变x本身的价值。哎呀!