MathGroup Archive 2003

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

Search the Archive

Re: split a list

  • To: mathgroup at smc.vnet.net
  • Subject: [mg40579] Re: [mg40515] split a list
  • From: Rob Pratt <rpratt at email.unc.edu>
  • Date: Thu, 10 Apr 2003 03:41:59 -0400 (EDT)
  • Sender: owner-wri-mathgroup at wolfram.com

On Wed, 9 Apr 2003, 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


Roberto,


Below are eight ideas, two of them one-liners.

If you hadn't required u and v to preserve the order and multiplicities of
r, the use of Complement would speed things up.

split[1] is your version
split[2] changes the For loop to a Scan
split[3] provides an alternative to AppendTo
split[4] provides a much faster alternative to AppendTo
split[5] and split[6] are fast and simple one-liners (but use two passes)
split[7] and split[8] use Fold but are the slowest of the eight

In[1]:= <<split.m

In[2]:= ?split
Global`split

split[1][r_List, m_] := Module[{u, v, tmp},
    u = v = {}; For[i = 1, i <= Length[r], i++, tmp = r[[i]];
       If[tmp > m, AppendTo[u, tmp], AppendTo[v, tmp]]; ]; {u, v}]

split[2][r_List, m_] := Module[{u, v}, u = v = {};
     Scan[If[#1 > m, AppendTo[u, #1], AppendTo[v, #1]] & , r]; {u, v}]

split[3][r_List, m_] := Module[{u, v}, u = v = {};
     Scan[If[#1 > m, u = Join[u, {#1}], v = Join[v, {#1}]] & , r]; {u, v}]

split[4][r_List, m_] := Module[{u, v}, u = v = {};
     Scan[If[#1 > m, u = {u, #1}, v = {v, #1}] & , r]; Flatten /@ {u, v}]

split[5][r_List, m_] := {Select[r, #1 > m & ], Select[r, #1 <= m & ]}

split[6][r_List, m_] := {Cases[r, x_ /; x > m], Cases[r, x_ /; x <= m]}

split[7][r_List, m_] := Fold[If[#2 > m, {Join[First[#1], {#2}], Last[#1]},
      {First[#1], Join[Last[#1], {#2}]}] & , {{}, {}}, r]

split[8][r_List, m_] := {Fold[If[#2 > m, Join[#1, {#2}], #1] & , {}, r],
    Fold[If[#2 <= m, Join[#1, {#2}], #1] & , {}, r]}

In[3]:= r=Table[Random[],{10000}];

In[4]:= Equal@@Table[split[k][r,0.5],{k,1,8}]

Out[4]= True

In[5]:= Table[First[Timing[split[k][r,0.5]]],{k,1,8}]

Out[5]= {7.31 Second, 6.97 Second, 8.31 Second, 0.49 Second, 0.38 Second,

>    0.51 Second, 8.88 Second, 9.26 Second}


Rob Pratt
Department of Operations Research
The University of North Carolina at Chapel Hill

rpratt at email.unc.edu

http://www.unc.edu/~rpratt/



  • Prev by Date: Re: numerical integration
  • Next by Date: RE: Prefix notation
  • Previous by thread: Re: split a list
  • Next by thread: RE: split a list