MathGroup Archive 2003

[Date Index] [Thread Index] [Author Index]

Search the Archive

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
>
>
>
>



  • Prev by Date: Re: split a list
  • Next by Date: Re: split a list
  • Previous by thread: Re: Re: split a list
  • Next by thread: Re: split a list