# Assigning to multiple variables in a list the values in another list

I have two lists, one contains the variables and the other the corresponding values that the variables should take.

letters = {"a","m","t","h","e"}
bonus = {10, 20, 30, 40, 50}
words = {math, the, gps, log}


I know that this works (as in the manual of Mathematica):

{a,b,c} = {10,20,30}


But the lists are rather long, so I would like to write:

letters = bonus


Which does not work. Output: I would like to have the variables (letters) taking the values (bonus) a=10, b=20, c=30. Having the weight of the letters, it should be possible to compute the weight of every word in list "words" [math (100), the (120) etc.] I would appreciate some pointers to get me started. Thank you for your time.

• The items in your "letters" List are Strings not Symbols and therefore can't be assigned values. You might be better off creating a Rule for the letter values. Mar 12, 2016 at 20:28
• You can try Clear[letters]; Evaluate@(Symbol /@ letters) = bonus. This will create symbols from your strings, then assign them a value, i.e. a=10 etc. Beware that the Clear bit is important if you plan to run this code more than once. Notice, however, that you are NOT assigning a value TO THE STRING "a", but to the symbol a. This may still not work for what you want. An Association construct would probably work a lot better. Mar 12, 2016 at 20:31
• @Xavier, @Quantum_Oli, @garej - I used "// Timing" to time the processes. The three answers below demand different times with a dictionary of about 240 thousand words. Plus: 0.005087, Total: 0.013299 and Map: 0.039653. The Plus solution is thus the quickest.
– JSP
Mar 14, 2016 at 15:48

## 3 Answers

Using associations:

letters = {"a","m","t","h","e"};
bonus = {10, 20, 30, 40, 50};
words = {math, the, gps, log};

assoc = AssociationThread[letters -> bonus];

Plus @@@ (Lookup[assoc, #, 0] & /@ Characters[ToString /@ words])

(* {100, 120, 0, 0} *)


If the words are strings, rather than symbols, then simply Characters[words] instead of Characters[ToString /@ words].

• Sorry for the delay before responding, I have been travelling. Thank you @Xavier, It works like a charm. I have to understand Associations. Every time I get here I learn something.
– JSP
Mar 14, 2016 at 15:11
• Re: associations -- You may find this post (52393) useful.
– user31159
Mar 14, 2016 at 15:29

Converting your words to strings first:

    letters = {"a", "m", "t", "h", "e"}
bonus = {10, 20, 30, 40, 50}
words = {"math", "the", "gps", "log"}


We can create a list of rules for the values of letters (rather than assign values to many variables):

    Thread[letters -> bonus]


{"a" -> 10, "m" -> 20, "t" -> 30, "h" -> 40, "e" -> 50}

Then we can use Characters to split each word into a list of it's characters:

    Characters /@ words


{{"m", "a", "t", "h"}, {"t", "h", "e"}, {"g", "p", "s"}, {"l", "o", "g"}}

Putting it all together:

    Total /@ ((Characters /@ words) /. Thread[letters -> bonus])


{100, 120, "g" + "p" + "s", "g" + "l" + "o"}

• Sorry for the delay before responding, I have been travelling. Thank you @Quantum_Oli, It works like a charm. Every time I get here I learn something. It is especially useful with such a pedagogical explanation!
– JSP
Mar 14, 2016 at 15:15
letters = {"a", "m", "t", "h", "e"};
bonus = {10, 20, 30, 40, 50};
words = {math, the, gps, log};


Solution:

Map[Total @ Replace[#, Append[Thread[letters -> bonus], _ -> 0], 1] &,
Characters[ToString /@ words]]


{100, 120, 0, 0}

• Thank you @garey, it also works nicely. I will try to find the timings for all three solutions (if I can do that). I do not understand the "_->0". Where can I read about it? Thanks.
– JSP
Mar 14, 2016 at 15:23
• @JSP, This is a pattern with Rule. You may see that Raplace expects a pattern as an option. So your letter->score are simple replacement rules that applied first. Then _->0 construct applies (it replaces all the rest letters in characters list). It means "replace any symbol to 0". Here _ is blank and stands for any symbol. Mar 14, 2016 at 15:31