2
$\begingroup$

If I use the Append command as follows,

Append[foo,1];

I will get an error that says

Append::normal: Nonatomic expression expected at position 1 in Append[foo,1]. 

The solution I use to avoid this is to define my list as an empty list early in my code:

foo1={};
foo2={};
(* 

A break where there may be a ton of code, maybe some loops


*)
foo1=Append[foo1,1];
foo2=Append[foo2,1];

This works fine of course, but I end up with a bunch of {} lines at the begging of my code, before the loops and other stuff.

Is there a way to use append for a list that is not yet defined?

$\endgroup$
  • 1
    $\begingroup$ foo1 = foo2 = {}; might be more compact? $\endgroup$ – Ruud3.1415 Sep 22 '17 at 14:46
  • 1
    $\begingroup$ Have you looked at the Sow and Reap functions? $\endgroup$ – Ruud3.1415 Sep 22 '17 at 14:47
  • 3
    $\begingroup$ As hinted at by @Ruud3.1415, it's quite likely that there are better ways to do whatever it is you're trying to do. The construction that you're using is standard in procedural languages, but it is not idiomatic in Mathematica, and usually you can do things much faster and simpler using a functional method. In other words, try to avoid loops in Mathematica. $\endgroup$ – march Sep 22 '17 at 15:46
  • $\begingroup$ One more note: if you're going to Append to a variable (sometimes it's convenient for a one-off addition to a list), you might as well use AppendTo, which is more concise. $\endgroup$ – Sjoerd Smit Sep 22 '17 at 21:27
  • $\begingroup$ You could also use linked lists as a more efficient way of appending elements to a data structure. $\endgroup$ – Sascha Sep 23 '17 at 0:52
4
$\begingroup$

I would do something like:

{foo1,foo2}=Last[Reap[
(* 

A break where there may be a ton of code, maybe some loops


*)
Sow[1,tag1];
Sow[1,tag2];
,{tag1,tag2}]];
$\endgroup$
4
$\begingroup$

To avoid initializing any of your lists, you may wish to consider defining myAppend as follows:

Clear[myAppend]
myAppend[foo_List, stuff_] := Append[foo, stuff]
myAppend[foo_Symbol, stuff_] := {stuff}

You would then use myAppend instead of Append, with initialized lists or with uninitialized symbols, as in the this example:

Clear[foo1, foo2]
foo1 = {1, 2, 3};

myAppend[foo1, "a"]
myAppend[foo2, "b"]

myAppend returns a list in both cases, so it could be used instead of Append in your example. myAppend does not clobber existing lists.

Your example contains instances where you actually performing something like an AppendTo the list. That is, you are replacing the old list with the updated list. Here is an example of a myAppendTo function that will append the new data and replace your old list with the new one:

Clear[myAppendTo]
SetAttributes[myAppendTo, HoldFirst]
myAppendTo[foo_, stuff_] := (foo = myAppend[foo, stuff];)

Clear[foo1, foo2]
foo1 = {1, 2, 3};

myAppendTo[foo1, "a"]
myAppendTo[foo2, "b"]

{foo1, foo2}

(*  {{1, 2, 3, "a"}, {"b"}}  *)

Notice that myAppendTo does not return a value, but it does replace the old list, if any, with the new list.

$\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.