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/