I do not think my explicit code will be helpful to illustrate it so here is the "barebones" silly example:
AbsoluteTiming[K = {};
M = {};
L = {};
Do[m = RandomReal[{-10, 10}] ;
If[m > 0, AppendTo[K, m],
If[m == 0, AppendTo[M, m], AppendTo[L, m]]], 100000] ;
K;
M;
L;]
I used Apppend originally since that is the only command I knew and I had like 6 sets to append to and a lot of nested If's. I am now optimizing my code, I really need to make it faster, and the first thing I am attempting is fixing these AppendTo. I do not see how to use table so that I get a few lists depending on some if statements. However, I came up with the following code using Sow and Reap:
AbsoluteTiming[JJ = Reap[Reap[Reap[Do[m = RandomReal[{-10, 10}] ;
If[m > 0, Sow[m, 1], If[m == 0, Sow[m, 2], Sow[m, 3]]], 10],
1], 2], 3]
K = Flatten[Flatten[JJ[[2]], 2][[2]]];
M = Flatten[JJ[[2]], 1][[2]];
L = Flatten[JJ[[2]], 1][[3]];]
Which seems to be around 80 000 times faster! That is great. Is there any other way to improve this? I do not like the Reap and Sow commands as I will need to deal with like 7 tags and somehow figure out how to get to them from the huge Reap.
Any suggestions would be helpful. Also if you have any hints on how to make nested If's more manageable visually (so that I know which If statement I am in) I would appreciate that.
Edit:
AbsoluteTiming[yourList = RandomReal[{-10, 10}, 100000];
f[m_] := Which[m > 0, "positive", m == 0, "zero", m < 0, "negative"];
grouped = GroupBy[yourList, f];
grouped["positive"];
grouped["zero"];
grouped["negative"];]
Reap
s—oneReap
captures everySow
inside! $\endgroup$Reap[Reap[Reap[expr, patt1], patt2], patt3]
you can useReap[expr, {patt1, patt2, patt3}]
. Each reaped expression should appear then in a separate list, in the order the tags appear. Unless I'm misunderstanding which empty list you want to appear? $\endgroup$