如何将值设置为符号

wro*_*ame 5 symbols wolfram-mathematica

我想将值设置为变量列表,如下所示:

list[[1]] = 2
Run Code Online (Sandbox Code Playgroud)

如果list[[1]]a,那么a现在将等于两个.我怎样才能做到这一点?

Sjo*_*ies 9

好吧,让我们天真地尝试一下:

做一个列表:

In[1]:= ClearAll[list, a, b, c]; 
list = {a, b, c}; 
Run Code Online (Sandbox Code Playgroud)

这是我们所期望的:

In[3]:= list
Out[3]= {a, b, c}
Run Code Online (Sandbox Code Playgroud)

将第一个元素设置为2:

In[4]:= list[[1]] = 2
Out[4]= 2

In[5]:= list
Out[5]= {2, b, c}
Run Code Online (Sandbox Code Playgroud)

这不会影响:

In[6]:= a 
Out[6]= a
Run Code Online (Sandbox Code Playgroud)

重新开始:

In[7]:= ClearAll[list, a, b, c]; 
list = {a, b, c}; 

In[9]:= list
Out[9]= {a, b, c}
Run Code Online (Sandbox Code Playgroud)

问题是Set(=)具有HoldFirst其属性之一,即它不评估其第一个参数是左侧,并且赋值是列表而不是该位置中的变量.但你可以使用Evaluate以下方法强制评估

In[10]:= Evaluate[list[[1]]] = 2
Out[10]= 2
Run Code Online (Sandbox Code Playgroud)

现在列表似乎和以前一样:

In[11]:= list
Out[11]= {2, b, c}
Run Code Online (Sandbox Code Playgroud)

但这只是因为a仍然存在并且值为2(在之前的版本中a被2 替换):

In[12]:= a
Out[12]= 2
Run Code Online (Sandbox Code Playgroud)

如果您现在将a设置为3,您将看到更改列表:

In[13]:= a = 3
Out[13]= 3

In[14]:= list
Out[14]= {3, b, c}
Run Code Online (Sandbox Code Playgroud)

编辑

也许更接近你的问题的措辞,你可以Map Set在列表上:

In[16]:= ClearAll[list, a, b, c]; 
list = {a, b, c}; 

In[18]:= Set[#, RandomInteger[10]] & /@ list
Out[18]= {4, 8, 1}

In[19]:= list    
Out[19]= {4, 8, 1}

In[21]:= {a, b, c}    
Out[21]= {4, 8, 1}
Run Code Online (Sandbox Code Playgroud)


Leo*_*rin 9

您在Mathematica中要求的通常很难,因为很难模仿指针语义.以下代码将专门针对您的要求,但仅限于符号作为列表元素:

ClearAll[setPart];
SetAttributes[setPart, HoldFirst];
setPart[lst_Symbol, i_, value_] :=
  With[{heldPart =  First@Extract[Hold[lst] /. OwnValues[lst], {{1, i}}, Hold]},
    If[MatchQ[heldPart, Hold[_Symbol]],
      Set @@ Append[heldPart, value],
      lst[[i]] = value]];
Run Code Online (Sandbox Code Playgroud)

例子:

In[117]:= Clear[list, a, b]
list = {a, b, c, 4, 5};
a = 1;
b = 3;
list

Out[121]= {1, 3, c, 4, 5}

In[122]:= setPart[list, 1, 10];
{a, list}

Out[123]= {10, {10, 3, c, 4, 5}}

In[124]:= setPart[list, 5, 10];
list

Out[125]= {10, 3, c, 4, 10}
Run Code Online (Sandbox Code Playgroud)