wro*_*ame 5 symbols wolfram-mathematica
我想将值设置为变量列表,如下所示:
list[[1]] = 2
Run Code Online (Sandbox Code Playgroud)
如果list[[1]]
是a
,那么a
现在将等于两个.我怎样才能做到这一点?
好吧,让我们天真地尝试一下:
做一个列表:
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)
您在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)