This code adds random digits to lists, and it works fine:
a = {{1}, {2}, {3}};
Do[
j = RandomInteger[{1, Length[a]}];
AppendTo[a[[j]], RandomInteger[9]];
Print[a], {i, 5}];
(* {{1,7},{2},{3}}
{{1,7},{2,2},{3}}
{{1,7},{2,2},{3,9}}
{{1,7},{2,2},{3,9,1}}
{{1,7,2},{2,2},{3,9,1}} *)
But if I replace the 'j' inside the [[]] with the definition j in the previous line, everything goes haywire:
a = {{1}, {2}, {3}};
Do[
AppendTo[a[[RandomInteger[{1, Length[a]}]]], RandomInteger[9]];
Print[a], {i, 5}];
(* {{1},{1,7},{3}}
{{1},{1,7},{1,4}}
{{1,7},{1,7},{1,4}}
{{1,7},{1,7},{1,7,9}}
{{1,7,9},{1,7},{1,7,9}} *)
Is this a bug or something I'm doing wrong?
Answer
Here's the issue. In the second (non-working) code,
RandomInteger[{1, Length[a]}]
is evaluated twice, as we can see by Trace
ing the evaluation:
SeedRandom[2]
a = {{1}, {2}, {3}};
Trace[AppendTo[a[[RandomInteger[{1, Length[a]}]]], RandomInteger[9]], TraceInternal -> True]
{RandomInteger[9], 8}
AppendTo[a[[RandomInteger[{1, Length[a]}]]], 8]
{{a, {{1}, {2}, {3}}}, {{{{a, {{1}, {2}, {3}}}, Length[{{1}, {2}, {3}}], 3}, {1, 3}}, RandomInteger[{1, 3}], 3}, {{1}, {2}, {3}}[[3]], {3}}
a[[RandomInteger[{1, Length[a]}]]] = Append[{3}, 8]
{Append[{3}, 8], {3, 8}}
a[[RandomInteger[{1, Length[a]}]]] = {3, 8}
{{{{a, {{1}, {2}, {3}}}, Length[{{1}, {2}, {3}}], 3}, {1, 3}}, RandomInteger[{1, 3}], 2}
We can see in Line 1 that RandomInteger[9]
evaluates to 8, so we will be appending 8 to one of the lists. In Line 3, RandomInteger[{1, 3}]
evaluates to 3, so we're going to append to a[[3]]
. This happens on Line 5, where 8 is appended to {3} to make {3, 8}.
Now, the kicker: In Line 7, RandomInteger[{1, Length[a]}]
is evaluated again, so it evaluates to a different number. In this case, it evaluates to 2, so instead of replacing a[[3]]
, we are replacing a[[2]]
with {3, 8}
. Hence the output after this evaluation is
a
(* {{1}, {3, 8}, {3}} *)
Now, the fix here is to do things the way you're doing it in the first code. I would probably wrap the entire thing in a Module
with j
as a local variable, but it's the same process.
Comments
Post a Comment