# How to use AppendTo in a While loop? [closed]

I am trying to code a while loop that uses AppendTo to append the loop variable to an empty list.

even = {}
i = 1; While[i <= 5, Print[i]; AppendTo[even, i]; i++]


This code does not give any output. Can someone please tell what I am doing wrong? Thanks!

• The code is not intended to give an output. It alters the symbol even five times, then even contains the (desired?) output - all numbers, not only the even ones. – mgamer Jul 22 '19 at 15:40
• It should be noted that the AppendTo function isn't ideal for loops. The documentation explains in more detail. – BioPhysicist Jul 23 '19 at 14:53
• Can you explain why you expect this piece of code to return a value (an output) at all? While does not return anything. If it did, what would be a reasonable thing for it to return? – Szabolcs Jul 24 '19 at 8:44

Try

even = {} ;
i = 1;
While[i <= 5, Print[i];If[EvenQ[i], AppendTo[even, i]]; i++]

even
(*{2, 4}*)


The standard Table function also supports multi-line inputs, the last line will be used to create the table

Table[Print[i]; i, {i, 5}]


The output would look like this:

even = Table[Print[i]; i, {i, 5}]

1
2
3
4
5
{1, 2, 3, 4, 5}


But the value stored for even is just:

{1, 2, 3, 4, 5}


Linked lists (see Performance tuning in Mathematica?) are another, efficient alternative.

even = {}
i = 1; While[i <= 5, even = {even, i}; i++]

Flatten[even]

(*  { 1, 2, 3, 4, 5 }  *)


(I don't know why people use Print[] except for debugging. I suppose it's a C thing. To monitor progress, you can use Monitor[] or my current favorite, PrintTemporary@Dynamic@{Clock[Infinity], i}. To output data, there are better ways than Print[].)

Sow/Reap is more appropriate than AppendTo in the context of step-by-step list building: the latter takes longer as your list gets longer, whereas the former keeps up its speed until the end.

i = 1;
even = Reap[While[i <= 5, Print[i]; Sow[i]; i++]][[2, 1]]
(*    1    *)
(*    2    *)
(*    3    *)
(*    4    *)
(*    5    *)
(*    {1, 2, 3, 4, 5}    *)


Of course, this is only useful if you do something more complex in the loop. For this particular case, Table is even better, as user2757771 points out.

Just to go overkill on Michael E2's point that Print is pretty much useless except in a debug environment, here's a little automated Monitor:

monitored~SetAttributes~HoldAll;
monitored[
monitoredVars : {__Symbol} | Automatic : Automatic,
expr_,
ignoredContexts : StringPatternStringPatternQ : "System"
] :=
Replace[
If[Hold[monitoredVars] === Hold[Automatic],
DeleteDuplicates@
Cases[Hold[expr],
s_Symbol?(Function[Null, ! StringMatchQ[Context[#], ignoredContexts],
HoldFirst]) :>
Hold[s],
Infinity
],
Hold
],
Hold[monitoredVars]
],
Hold[mvars_] :>
(
PrintTemporary@
InternalLoadingPanel@Dynamic[
Grid[
{
{"Time:", NumberForm[Quantity[Clock[Infinity], "Seconds"], 3]},
{"Vars:",
Grid[
{Row@{Extract[#, 1, Defer], ":"}, ReleaseHold[#]} & /@
Alignment -> {Left, Top}
]
}
},
Alignment -> Left
]
];
expr
)
]


Then we can watch what happens (the Pause is just there to be able to see it happen):

monitored[
even = {};
n = 50;
i = 1; While[i <= n, Pause[.1]; even = {even, i}; i++];
Flatten[even]
]

{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, \
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, \
41, 42, 43, 44, 45, 46, 47, 48, 49, 50}


We can also just watch i:

monitored[
{i},
even = {};
n = 25;
i = 1; While[i <= n, Pause[.1]; even = {even, i}; i++];
Flatten[even]
]

{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, \
22, 23, 24, 25}


If you wanted to Print the list at the end of the While loop, you can do the following

Module[{even = List[], i},
i = 1;
While[i <= 5,
Print["Now appending " <> ToString[i] <> " to the list"];
AppendTo[even, i]; i++];
even
]


Just for fun, going full functional, and making use of the magic Nothing symbol:

feven[n_?EvenQ] := n
feven[_] = Nothing;
Map[feven, Range[5]]
(* {2, 4} *)


If you must see the input, you can look at what Range[5] yields.

This kind of approach helps speed things up if the function you're mapping to the input is complicated and expensive. In that case, use ParallelMap`. Factoring the problem into simple functions you can try out before composing higher level (but still simple) expressions from them also avoids much difficult debugging.