# Is there a workaround to dereference a list element that's the name of an undefined symbol, and iteratively assign values to the symbols in the list?

The title mostly covers what I would like to do. The image below shows in some situations it is possible dereference an element in a list using Evaluate to assign a value:

a[[0]]
(*Symbol*)
vars = {a, b, c}
Evaluate[vars[[1]]] = 1
{a[[0]], a}
(*{Integer, 1}*)


However, trying to do this for several items in a list with an explicit pure function map doesn't fair as well (likely because "The expression #1 cannot be used as a part specification"):

ClearAll[a, b, c]
Evaluate[vars[[#]]] = # & /@ Range[3]
(*Part::pkspec1: The expression #1 cannot be used as a part specification. >>*)
(*Set::setps: {a,b,c} in the part assignment is not a symbol. >>*)
(* ... compared to below which works ... *)
Evaluate[vars[[#]]] == # & /@ Range[3]
(*{a == 1, b == 2, c == 3}*)


Ideally I'd like to use MapThread for this particular task, but that doesn't appear to work either:

MapThread[Evaluate[[#1]] = #2 &, {vars, {1, 2, 3}}]
(* Set::pkspec1: The expression #1 cannot be used as a part specification. >> *)


Any tips or workarounds on how to pull something like this off?

Thanks for any help!

• Post the code so that anyone can easy to test it. – cvgmt Nov 7 '20 at 4:10
• Syntax coloring indicates you need parentheses. – Carl Woll Nov 7 '20 at 4:20
• @CarlWoll Thanks for that, I noticed the syntax error coloring myself, but I've tried (...), {...}, and [...] around the # in vars[[#]] and different attempts at escaping the result, but to no avail. Any suggestions? – Dustin Darcy Nov 7 '20 at 4:36

(Evaluate@vars[[#]] = #) & /@ Range[3]

• Thanks @asd1dsa is there a reason you prefer prefix form over say (Evaluate[vars[[#]]] = #) & /@ Range[3]? Either way it worked, much appreciated! – Dustin Darcy Nov 7 '20 at 4:50
• @DustinDarcy I use prefix for readability. Triple nested [ ] is hard to read, isn't it? If you are not familiar with the precedence, paratheses are OK. – asd1dsa Nov 7 '20 at 4:53

Rather than MapThread, I recommend Do for the more general case where the values are also taken from a list. Like so:

Clear[a, b, c]
vars = {a, b, c};
vals = {27, 16, 32};
Do[Evaluate[vars[[i]]] = vals[[i]], {i, Length @ vars}];
vars

{27, 16, 32}