This is a fairly natural question and I feel it is worthy of attention. I am going to answer in two parts. First, I am going to show a method that is more appropriate for Mathematica programming and which I recommend you use instead. Then I will show how to force the action you are attempting.
Better Alternatives
The common way to accomplish programmatically selected assignments is to use indexed variables. This allows you to assemble a "variable" from inert parts. For example, one would use a single variable var and simply make assignments (SeedRandom[1] for a consistent result):
SeedRandom[1] Do[ var[i] = RandomInteger[9], {i, {1, 2, 3, 2, 3, 1, 3}} ]
Or recall them:
var /@ {1, 2, 3}
{0, 7, 8}
If you desire a certain name be attached to a value you can index with Strings.
names = {"aaa", "bbb", "ccc"}; i = 1; var[ names[[i]] ] = Sqrt[2]; (* dummy first assignment *) var[ names[[i]] ] = {1, 2, 3, 4, 5}; var["aaa"]
{1, 2, 3, 4, 5}
In passing, depending on your application you may find Rules applicable.
Associations
Mathematica 10 introduced Associations which are like self-contained "indexed variables." Use is similar but you need to start with an (optionally empty) Association before you make assignments. Example:
SeedRandom[1] asc = <||>; Do[asc[i] = RandomInteger[9], {i, {1, 2, 3, 2, 3, 1, 3}}] asc
<|1 -> 0, 2 -> 7, 3 -> 8|>
Values may be recalled using Map, Replace, or Lookup; for a comparison see:
For some ideas of when and why one might use associations over "indexed variables" see:
Forcing the behavior
Suppose you need the behavior you asked for to keep a large program working without extensive modification.
Method #1
This works because Part preserves the head of the expression, here Unevaluated.
Ignore the syntax highlighting in Unevaluated: this is a nonstandard but safe use.
This could easily use the same syntax as Method #2: assign[symbols_, idx_, val_] :=
ClearAll[aaa, bbb, ccc, assign] assign[idx_, val_] := (# = val) & @ symbols[[1, {idx}]] symbols = Hold @ Unevaluated[aaa, bbb, ccc]; assign[1, "dummy"]; assign[1, Range@5]; aaa
{1, 2, 3, 4, 5}
Method #2
This uses the injector pattern in preference to Unevaluated.
ClearAll[aaa, bbb, ccc, f1, assign] assign[symbols_, idx_, val_] := symbols[[{idx}]] /. _[x_] :> (x = val) symbols = Hold[aaa, bbb, ccc]; assign[symbols, 1, "dummy"]; assign[symbols, 1, Range@5]; aaa
{1, 2, 3, 4, 5}