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/