Wolfram mathematica Set::setps:在零件分配中不是符号&燃气轮机&燃气轮机;

Wolfram mathematica Set::setps:在零件分配中不是符号&燃气轮机&燃气轮机;,wolfram-mathematica,Wolfram Mathematica,我在Mathematica中定义了一个函数,其中如果列表中的第I个值为1,并且第I+1个值为0,则该函数将切换这两个值 我将其定义为: f[i_, x_] := (If[x[[i]] == 1 && x[[i + 1]] == 0, x[[i]] = 1; x[[i + 1]] = 0]); 然而,当我用I=2和x={1,1,0,0}测试它时,我得到以下错误: Set::setps:{1,1,0,0}在零件分配中不是符号。>> 我不太清楚我做错了什么,因为我以为我把所有的事情都

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

我将其定义为:

f[i_, x_] := (If[x[[i]] == 1 && x[[i + 1]] == 0, x[[i]] = 1; x[[i + 1]] = 0]);
然而,当我用
I=2
x={1,1,0,0}
测试它时,我得到以下错误:

Set::setps:{1,1,0,0}在零件分配中不是符号。>>


我不太清楚我做错了什么,因为我以为我把所有的事情都说对了;我不需要改变x本身的值。哎呀

您似乎找到了解决方案,但还是让我们来分析一下

首先,出现一个简单的转录错误,
Set
s应用原始值,而不是交换原始值。通过此更改,基本代码可以工作:

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

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

x
因此,我们成功地更改了
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
也许您不打算更改
x
本身的值,但这种技术肯定会在其他应用程序中派上用场。要修改上述函数以操作数据副本,我们可以使用
模块
,并且不需要保留属性:

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]
请注意,
模块中的
x
是一个局部变量,而不是保持不变的全局列表
x

为了好玩,让我们用不同的方式实现它

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

f3[2, x]
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}
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}