Re: split a list
- To: mathgroup at smc.vnet.net
- Subject: [mg40564] Re: [mg40515] split a list
- From: Andrzej Kozlowski <akoz at mimuw.edu.pl>
- Date: Thu, 10 Apr 2003 03:39:07 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
Actually, yours is possibly the most inefficient way to do this (in Mathematica of course, not in C). To see this let's turn it into a function: spl1[r_, m_] := Module[{u = {}, v = {}}, For[i = 1, i ¡Â Length[r], i++, tmp = r[[i]]; If[tmp > m, AppendTo[u, tmp], AppendTo[v, tmp]];]; {u, v}] Let's compare it with one of the most obious ways to do this in Mathematica: spl2[ls_, m_] := {Cases[ls, _?(# > m &)], Cases[ls, _?(# ¡Â m &)]} Let's take a fairly size test example: r = Table[Random[], {10^4}]; You can see a pretty big difference in performance: res1=spl1[r,0.5];//Timing {11.89 Second,Null} res2=spl2[r,0.5];//Timing {0.34 Second,Null} If one wants to do better than spl2 one should probably try to write a function that can be compiled (spl2 can't because the Mathematica compiler can't deal with patterns). I have not been able to see any obvious way to do this in a singe step but here is a possible two step approach: first a compiled auxiliary function: f=Compile[{{r,_Real,1},{m,_Real,0}},Block[{n=Max[r]+1},Transpose[{If[#> m,#,n],If[#<=0.5,#,n]}&/@r]]]; then a non-compiled splitting function, which relies on f: spl3[r_,m_]:=DeleteCases[f[r,m],Max[r]+1,Infinity] This beats spl2: res3=spl3[r,0.5];//Timing {0.13 Second,Null} We can check that all the answers agree: In[23]:= res1==res2==res3 Out[23]= True I am sure this can be much improved but this is as much time as I am prepared to spend on this. Andrzej Kozlowski Yokohama, Japan http://www.mimuw.edu.pl/~akoz/ http://platon.c.u-tokyo.ac.jp/andrzej/ On Wednesday, April 9, 2003, at 02:30 pm, Roberto Brambilla wrote: > Hi, > > I have a list (very long, thousands, and unsorted) of numbers > r={n1,n2...} > and for a given a number m I want to split it in the two sublists > (unsorted, same order) u={elements<m], v={elements>m}. > Now I use this *old-style* method: > > u = v = {}; > For[i = 1, i <= Length[r], i++, > tmp = r[[i]]; > If[tmp > m , AppendTo[u, tmp], AppendTo[v, tmp]]; > ] > > Any suggestion for a more efficient (and elegant) method? > Also oneliners are well accepted. > > Many thanks, Roberto > > Roberto Brambilla > CESI > Via Rubattino 54 > 20134 Milano > tel +39.02.2125.5875 > fax +39.02.2125.5492 > rlbrambilla at cesi.it > > > >