2
$\begingroup$

How can I assign many values each to a different variable?

For example, I want to set $a = f(1),\,b = f(2),\,c = f(3),\,\dots,\,z = f(26)$ (generally more variables than these). How can I do this using a loop statement? I have tried to put the letters in a matrix, then give values to the matrix elements, but my letters didn't get any values.

$\endgroup$

marked as duplicate by m_goldberg, Jens, MarcoB, user9660, Mr.Wizard Jul 13 '16 at 6:02

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 4
    $\begingroup$ Does this fit your needs? How do you programatically load data into symbols? $\endgroup$ – Kuba Jul 12 '16 at 19:52
  • 1
    $\begingroup$ Why do you not want to just use Table? All the fancy alternatives may be completely unnecessary unless you provide a reason why Table isn't useful to you. $\endgroup$ – Jens Jul 12 '16 at 20:48
  • $\begingroup$ These may be even better duplicates but I already voted: (280), (6511) $\endgroup$ – Mr.Wizard Jul 13 '16 at 6:04
8
$\begingroup$

First of all, please note that coding this way in Mathematica is asking for trouble. Use of (lots of) mutable variables is strongly discouraged. The following will show you why:

  1. Clearing all symbols a to z in case they have been assigned some values is not trivial to do automatically in one go as it necessitates the manipulation of the order of standard evaluation with Unevaluated or some variety of the Hold-family of functions.

    a = 1 (* Assigns the value 1 to the symbol a *)
    
    Alphabet[] //ToExpression [#, InputForm, Unevaluated] & // Map@Clear;
    
    (* a and all other letter symbols have been cleared *)
    
  2. Generate a list of pairs {someCharacter, f[indexOfCharacter]}

    list = {ToExpression@Alphabet[], f /@ Range@26 } // Transpose
    

    {{a, f[1]}, {b, f[2]}, {c, f[3]}, {d, f[4]}, {e, f[5]}, {f, f[6]}, {g, f[7]}, {h, f[8]}, {i, f[9]}, {j, f[10]}, {k, f[11]}, {l, f[12]}, {m, f[13]}, {n, f[14]}, {o, f[15]}, {p, f[16]}, {q, f[17]}, {r, f[18]}, {s, f[19]}, {t, f[20]}, {u, f[21]}, {v, f[22]}, {w, f[23]}, {x, f[24]}, {y, f[25]}, {z, f[26]}}

  3. Trying to Apply the Set(=) function via Apply[Set, list, 1] to the list of pair fails because f is both your "function" and a symbol in the list of letters.

    $RecursionLimit::reclim2: Recursion depth of 1024 exceeded during evaluation of f[6]. >>

  4. The solution is to name your "function" something else like func that is not in your list of letters

    list = {ToExpression@Alphabet[], func /@ Range@26 } //Transpose;
    Apply[Set, list, 1];
    

After step 4 your symbols a through to z have been set to func[someIndex]. I hope you see that even in a toy example like this heavy use of mutable variables is asking for trouble.

A better way is to use for instance an Association

Alphabet[] //ToExpression [#, InputForm, Unevaluated] & // Map@Clear;    

letters = AssociationThread[ToExpression@Alphabet[], f /@ Range@26]

<|a -> f[1], b -> f[2], c -> f[3], d -> f[4], e -> f[5], f -> f[6], g -> f[7], h -> f[8], i -> f[9], j -> f[10], k -> f[11], l -> f[12], m -> f[13], n -> f[14], o -> f[15], p -> f[16], q -> f[17], r -> f[18], s -> f[19], t -> f[20], u -> f[21], v -> f[22], w -> f[23], x -> f[24], y -> f[25], z -> f[26]|>

You can now call your letters via something like letters[a] which evaluates to f[1]

$\endgroup$
1
$\begingroup$

You could use a combination of Evaluate and FromLetterNumber

Evaluate[ToExpression[FromLetterNumber[Range[26]]]] = Array[func, 26]

Or, Thread is another option.

Thread[f1[ToExpression[FromLetterNumber[Range[26]]], Array[f2, 26]]] /. f1 -> Set
$\endgroup$
0
$\begingroup$

Maybe this could help:

(* If your data are saved in an array... *)
f={1.2,2.2,3.1,4.3};

(* generate the letters and assign the values: *)
ToExpression[Table["a"<>ToString[i]<>"="<>ToString[f[[i]]],{i,1,Dimensions[f][[1]]}]];

{a1,a2,a3,a4}

Out[3]= {1.2, 2.2, 3.1, 4.3}

OR...

(* Generate Random data... *)
F = Table[RandomReal[{-3, 3}], {i, 1, 26}];

Clear[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, 
  v, w, x, y, z];
letters = {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t,
    u, v, w, x, y, z};

Table[ToString[letters[[ii]]] <> "=" <> ToString[F[[ii]]], {ii, 1, 26}]
ToExpression[%]

a
b

This gives...

Out[4]={a=0.0177264,b=2.18909,c=1.36537,d=2.04752,e=2.43522,f=1.73921,g=-0.95031,h=-0.888718,i=-0.667,j=-1.88201,k=0.288534,l=2.11707,m=-0.893829,n=-1.1311,o=-2.61573,p=-1.11131,q=1.9456,r=-0.182795,s=2.705,t=-0.52068,u=-1.0116,v=0.339239,w=-2.40379,x=-2.88596,y=1.70749,z=-2.23369}

Out[5]={0.0177264,2.18909,1.36537,2.04752,2.43522,1.73921,-0.95031,-0.888718,-0.667,-1.88201,0.288534,2.11707,-0.893829,-1.1311,-2.61573,-1.11131,1.9456,-0.182795,2.705,-0.52068,-1.0116,0.339239,-2.40379,-2.88596,1.70749,-2.23369}

Out[6]=0.0177264

Out[7]=2.18909
$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.