1
$\begingroup$

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!

$\endgroup$
3
  • $\begingroup$ Post the code so that anyone can easy to test it. $\endgroup$ – cvgmt Nov 7 '20 at 4:10
  • 1
    $\begingroup$ Syntax coloring indicates you need parentheses. $\endgroup$ – Carl Woll Nov 7 '20 at 4:20
  • $\begingroup$ @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? $\endgroup$ – Dustin Darcy Nov 7 '20 at 4:36
1
$\begingroup$
(Evaluate@vars[[#]] = #) & /@ Range[3]
$\endgroup$
2
  • $\begingroup$ Thanks @asd1dsa is there a reason you prefer prefix form over say (Evaluate[vars[[#]]] = #) & /@ Range[3]? Either way it worked, much appreciated! $\endgroup$ – Dustin Darcy Nov 7 '20 at 4:50
  • $\begingroup$ @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. $\endgroup$ – asd1dsa Nov 7 '20 at 4:53
1
$\begingroup$

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}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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