2
$\begingroup$

This question already has an answer here:

as I'm well aware, using AppendTo for large lists isn't recommended as the function gets progressively slower with each appending done.

Lots of suggestions talk about using Reap and Sow, however the ones I found don't deal with nested lists. My question is relatively simple, how to substitute AppendTo with Reap, Sow as directly as possible?

Specific information regarding my problem: I would like to append data in form of

data = {{x}, {y}}

to a list, so after a few iterations, the list would look something like

list = {{{x1}, {y1}}, {{x2}, {y2}}, {{x3}, {y3}}}

My solution works for only 1 iteration, and then breaks apart because of increasing use of Flatten, so it's obviously a non-working solution. Of course, I'm open to other alternatives, faster than AppendTo.

$\endgroup$

marked as duplicate by Szabolcs, m_goldberg, MarcoB, user9660, Öskå May 7 '16 at 20:49

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • $\begingroup$ You can sow the x and y variables to different tags, then use Thread or Transpose to shape the separate x and y lists into the shape you want. Look at the second argument to Sow $\endgroup$ – Jason B. May 7 '16 at 9:53
  • 1
    $\begingroup$ If you always generate pairs {x,y}, what is the problem with Reap/Sow here? If you do list = Reap[ Do[ Sow[ {x[i], y[i]} ], {i,3} ] ][[2,1]] you get what you want, no Flattening needed. If you generate x and y separately, see @JasonB's comment. $\endgroup$ – Marius Ladegård Meyer May 7 '16 at 9:55
  • 1
    $\begingroup$ There is undocumented Internal`Bag described by Daniel Lichtblau in this answer. Look also at this thread for further discussion. $\endgroup$ – Alexey Popkov May 7 '16 at 10:52
  • $\begingroup$ @MariusLadegårdMeyer your suggestion did the trick, with the few modifications :) thanks to everyone! $\endgroup$ – blairo May 7 '16 at 11:17
3
$\begingroup$

Thanks to the suggestions above, I could replace the following use of AppendTo[]:

For[i=1,i<10,i++,
 data = {{x},{y}};
 AppendTo[list,data];
];

with the use of Reap[] and Sow[]:

list=Reap[
 For[i=1,i<10,i++,
  data={{x},{y}};
  Sow[data];
 ];
][[2, 1]];

The latter produces one extra set of outer curly brackets, which you can easily remove with Flatten[].

$\endgroup$
  • $\begingroup$ If you really need to loop, you should use Do instead of For. But probably there is a way to do what you want with Table instead, creating the list directly. Also, in you answer, there is no need whatsoever to include list={};. This is extremely rarely needed. $\endgroup$ – Marius Ladegård Meyer May 7 '16 at 12:00
  • 1
    $\begingroup$ Noted. The data collection is a part of a larger program, hence no table :) $\endgroup$ – blairo May 7 '16 at 12:22
  • $\begingroup$ Seems to me that list = Table[{{x}, {y}}, {i, 9}] is shorter and clearer. $\endgroup$ – bill s May 7 '16 at 12:50

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