MathGroup Archive 2010

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

Search the Archive

Re: Sorting nested lists

  • To: mathgroup at smc.vnet.net
  • Subject: [mg108480] Re: Sorting nested lists
  • From: Leonid Shifrin <lshifr at gmail.com>
  • Date: Fri, 19 Mar 2010 06:45:20 -0500 (EST)
  • References: <201003190746.CAA08430@smc.vnet.net>

Hi Kurt,

Here is your data:

In[2]:= data  = {{350.17, -43.6426, 1768.77}, {350.17, -43.5582,
   1259.67}, {350.17, -43.5308, 967.89}, {350.17, -43.5839,
   1689.8}, {350.17, -43.6445, 1753.05}, {350.17, -43.6114,
   2021.65}, {350.17, -43.5327, 977.36}, {350.17, -43.5601,
   1289.87}, {350.17, -43.5858, 1720.39}, {350.17, -43.6464, 1736.25}};

Here is a brute force solution

In[66]:= sorted =
 Sort[data, #1[[1]] < #2[[1]] || (#1[[1]] == #2[[1]] && #1[[2]] < #2[[2]])
&]

Out[66]= {{350.17, -43.6464, 1736.25}, {350.17, -43.6445,
  1753.05}, {350.17, -43.6426, 1768.77}, {350.17, -43.6114,
  2021.65}, {350.17, -43.5858, 1720.39}, {350.17, -43.5839,
  1689.8}, {350.17, -43.5601, 1289.87}, {350.17, -43.5582,
  1259.67}, {350.17, -43.5327, 977.36}, {350.17, -43.5308, 967.89}}

Here is another one, using canonical sort

In[68]:= sortedAlt   = data[[Ordering[data[[All, {1, 2}]]]]]

Out[68]= {{350.17, -43.6464, 1736.25}, {350.17, -43.6445,
  1753.05}, {350.17, -43.6426, 1768.77}, {350.17, -43.6114,
  2021.65}, {350.17, -43.5858, 1720.39}, {350.17, -43.5839,
  1689.8}, {350.17, -43.5601, 1289.87}, {350.17, -43.5582,
  1259.67}, {350.17, -43.5327, 977.36}, {350.17, -43.5308, 967.89}}


The results will not generally be identical since your instruction does not
specify how to
compare elements for which both first and second numbers are the same, and
the two methods
treat them differently. If this does not matter to you, I'd recommend the
second method
since it offers considerable speed advantage on large lists:

In[62]:= largeData = RandomInteger[{1, 10}, {100000, 3}];

In[63]:= (largeSorted   =
    Sort[largeData, (#1[[1]] < #2[[1]]) || (#1[[1]] == #2[[1]] && \
#1[[2]] < #2[[2]]) &]); // Timing

Out[63]= {6.86, Null}

In[64]:= (largeSortedAlt =
    largeData[[Ordering[largeData[[All, {1, 2}]]]]]); // Timing

Out[64]= {0.031, Null}

In this benchmark, the second method is about 200 times faster than the
first. In the first method, you can improve efficiency somewhat by compiling
your comparison function:

In[69]:= compF  =
 Compile[{{x, _Real, 1}, {y, _Real, 1}},
  (x[[1]] < y[[1]]) || (x[[1]] == y[[1]] && x[[2]] < y[[2]])]

In[70]:=  Sort[largeData, compF]; // Timing

Out[70]= {2.032, Null}

Hope this helps.

Regards,
Leonid



On Fri, Mar 19, 2010 at 10:46 AM, Canopus56 <canopus56 at yahoo.com> wrote:

> I have a list of x, y, z triples in the form:
> {{350.17,-43.6426,1768.
> 77},{350.17,-43.5582,1259.67},{350.17,-43.5308,967.89},{350.17,-43.5839,1689.8},{350.17,-43.6445,1753.05},{350.17,-43.6114,2021.65},{350.17,-43.5327,977.36},{350.17,-43.5601,1289.87},{350.17,-43.5858,1720.39},{350.17,-43.6464,1736.25}}
> How do I sort a nested list where I want the sort order to be major
> x-ascending, minor subsort with y-ascending?
> Thanks, Kurt
>
>



  • Prev by Date: Re: need something like ReplaceAllIndexed[]
  • Next by Date: Re: Function construction and also symmetric matrices
  • Previous by thread: Sorting nested lists
  • Next by thread: Re: Sorting nested lists