I would like to know if it's possible to use the content of a variable list of strings to create a new variable.
As an example:
str={"cow","monkey"}
these strings are extracted from a file. Now I would like to re开发者_StackOverflow社区fer to these strings as if it was a variable. So the variable cow could be set to {4,2,3}
or anything else. Any reference as str[[1]]
gives the string "cow" of course.
Any clues or is this a bad idea anyway?
Of course I could add info in the list I already have such as:
str={{"cow",{4,2,3}},{"monkey",{}}
but then I still won't be able to directly address cow as a variable.
The simplest would be to just manually use symbols cow
and monkey
rather than strings:
In[309]:=
cow = 1;
monkey = 2;
{cow, monkey}
Out[311]= {1, 2}
But this is probably not what you asked. If you want to automatically convert strings to variables, then what you have to do (if I understood the question correctly) is to first convert your strings to symbols, since symbols can be assigned values and used as variables:
Remove[cow,monkey];
str = {"cow", "monkey"};
str1 = ToExpression /@ str
{cow, monkey}
(I assume that symbols cow
and monkey
have not been used/defined). After that, you can use the answer for this question to assign to the variables based on their positions in str1
. However, the usefulness of this approach is also questionable.
What I think makes the most sense is to create so called indexed variables, such as
myIndexedVar["cow"] = 1;
myIndexedVar["monkey"] = 2;
where myIndexedVar
is essentially a hash-table of key-value pairs, with keys being your strings and values being whatever you want to assign to them. The process can be automated if needed.
EDIT
To illustrate assignments to such variables, here is a function which automates that:
assignVariables[varNames_List, values_List, hashName_Symbol ] /;
Length[varNames] == Length[values] :=
MapThread[(hashName[#1] = #2) &, {varNames, values}];
Here is how you can use it:
In[316]:= assignVariables[str,{{4,2,3},{}},myIndexedVar]
Out[316]= {{4,2,3},{}}
In[317]:= myIndexedVar["cow"]
Out[317]= {4,2,3}
In[318]:= myIndexedVar["monkey"]
Out[318]= {}
But again, this really is a hash-table, so your question makes most sense to me when reformulated as: "I want to make a hash-table with string keys. What's the easiest way to do that in Mathematica, add key-value pairs and access them". The answer seems to be - indexed variables, as illustrated above. You may also find it useful to read on DownValues, since these provide the mechanism for indexed variables.
Leonid's last method is probably the best, but I am fond of replacement rules, therefore I offer:
str={"cow","monkey"};
rules = {"cow" -> {4,2,3}, "monkey" -> {}};
str[[1]] /. rules
Out = {4, 2, 3}
See Rule
, and ReplaceAll
for more.
ToExpression
will convert a string to an expression. Symbol["x"]
creates the symbol x as the name suggests.
However, I wonder how you plan to use them. If you don't know a priori what's in the file with names how are you going to use them? If str={"cow","monkey"}
and I create a list of symbols with strSym=ToExpression/@str
then the only way I could continue in my code is to index this second array. I cannot simply say cow=5
in my code because I don't know at the time of writing the code that there will be a variable named cow.
In[1]:= str = {"cow", "monkey"};
strSym = ToExpression /@ str
Out[2]= {cow, monkey}
In[3]:= strSym[[1]] // Evaluate = 5
Out[3]= 5
In[4]:= ?cow
Global`cow
cow=5
As you can see, indexing also requires an additional Evaluate, because Set (=) has HoldFirst as Attribute. So I can't set cow by indexing unless I have the index evaluated otherwise I overwrite the definition of strSym[[1]] .
精彩评论