2011-04-18 67 views
5

我想值設置爲變量的列表,像這樣:如何設置值符號

list[[1]] = 2 

如果list[[1]]a,然後a現在將等於2。我怎樣才能做到這一點?

+0

如果我們知道的錯誤列表[[1]] = 2拋出 – ninjagecko 2011-04-18 20:06:10

回答

8

好吧,讓我們試試吧天真:

做一個列表:

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

這是因爲我們預計:

In[3]:= list 
Out[3]= {a, b, c} 

設置的第一個元素,以2:

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

In[5]:= list 
Out[5]= {2, b, c} 

這並不影響:

In[6]:= a 
Out[6]= a 

重新開始:

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

In[9]:= list 
Out[9]= {a, b, c} 

的問題是,設置(=)具有HoldFirst作爲它的一個屬性,即它不評估是左手邊的第一個參數,以及分配給列表而不是在那個位置的變量。但是你可以使用Evaluate力評價:

In[10]:= Evaluate[list[[1]]] = 2 
Out[10]= 2 

現在的名單似乎是和以前一樣:

In[11]:= list 
Out[11]= {2, b, c} 

但那只是因爲仍然存在,並已得到的2值(以在以前的版本是換成2):

In[12]:= a 
Out[12]= 2 

如果現在設置了3個,你會看到,太多的變化列表:

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

In[14]:= list 
Out[14]= {3, b, c} 

編輯

也許更接近你的問題的措辭,你可以MapSet在名單:

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} 
+0

很好的答案。簡單,有用,信息豐富。 +1 – 2011-04-18 22:46:57

+1

應該注意的是'Evaluate [list [[1]]] = 2'只有在'a'沒有任何價值時才能使用。除了編輯部分:'{a,b,c} = {1,2,3}'也可以。 – 2011-04-19 03:58:38

+0

@Alexey是的,這也可以工作,但我認爲OP有一個很長的變量列表,他想更自動地處理這些變量。第一個評論+1。事實上,在a得到一個值'Evaluate [list [[1]]]之後'評估它的值而不是符號。 – 2011-04-19 05:52:02

2

也許你可以這樣做:

setSymbol[symbol_, value_] := Module[{}, 
    ToExpression[ 
     SymbolName[symbol] <> "=" <> ToString[value,TotalWidth->Infinity] 
    ] 
] 
setSymbol[list[[1]], 2] 

雖然這可能是一個有點hackish。正確的方法是通過玩弄價值如何被評估,但我不記得如何;查看其他答案。

+0

非常hackish的,目前有錯誤,這將有助於。 'list [1]'應該是'list [[1]]',''=''應該是''=「',你可能打算使用'ToExpression'而不是'Evaluate'來將字符串轉回成爲將評估的東西。 – 2011-04-18 20:21:38

9

你要求什麼一般是很難的數學,因爲很難模仿指針語義。下面的代碼將做具體你問什麼,但僅限於符號列表元素:

ClearAll[setPart]; 
SetAttributes[setPart, HoldFirst]; 
setPart[lst_Symbol, i_, value_] := 
    With[{heldPart = [email protected][Hold[lst] /. OwnValues[lst], {{1, i}}, Hold]}, 
    If[MatchQ[heldPart, Hold[_Symbol]], 
     Set @@ Append[heldPart, value], 
     lst[[i]] = value]]; 

例子:

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} 
2

我也有類似的問題,定義符號的價值,當你第一次不知道你想重新定義的符號時。你的回答幫助我找到了正確的方法:

HoldPattern對我來說工作得很好,即使值已經爲變量設置了allready。

In[253]:= Clear[a,b,c,d,list] 
list = HoldPattern/@{a,b,c,d}; 
a=2; 
Evaluate[list[[1]]]=1; 
list//ReleaseHold 
a 

Out[257]= {1,b,c,d} 
Out[258]= 1 

所以我的解決辦法是很像由Sjoerd C.德弗里斯第一個解決方案,但它從列表中HoldPattern內被評估保護的符號。

請注意,必須使用ReleaseHold才能使用該列表進行進一步計算。變量(a,b,c,d)不會受到這種結構的影響。

這是我的第一篇文章在這裏,希望你喜歡它;-)