3
$\begingroup$

I have a list with these elements:

list={1/2 (1 + Sqrt[5]), 1, 1, 1/2 (1 - Sqrt[5]), 0};

enter image description here

I want to sort them with

Sort[list];

I see the bellow result:

enter image description here

Which is incorrect, because N[1/2 (1 - Sqrt[5])]= -0.6, However I can write Sort[N[list]] but I need to have the exact numbers, not their approximate values (I mean that I need 1/2 (1 - Sqrt[5]) instead of -0.6).

$\endgroup$
5
  • $\begingroup$ This seems like a bug, possibly related to this question. In any case, you can use Sort[list,N] to apply N before sorting (but keeping the original exact values). $\endgroup$
    – yohbs
    Sep 21, 2015 at 13:25
  • $\begingroup$ But it doesn't work: Sort[list, N, Less], because it has to be from Smaller to Larger, also, the command line is associated with a massage that I could not understand that's mean. $\endgroup$ Sep 21, 2015 at 13:31
  • $\begingroup$ This is a really weird behavior. I'm pretty sure it's a bug, and should be reported to Wolfram. In any case, you can solve your problem with Sort[list, N[#1] < N[#2] &] $\endgroup$
    – yohbs
    Sep 21, 2015 at 13:37
  • 2
    $\begingroup$ @yohbs, mr.0093 This is actually NOT a bug: this behavior may be counter-intuitive, but it is well described in the Sort documentation. This is also mentioned in the pitfalls FAQ: Using Sort incorrectly. $\endgroup$
    – MarcoB
    Sep 21, 2015 at 14:11
  • 1
    $\begingroup$ @mr.0093 Of course Ordering[] works. The point of Ordering[] is that your create a list of "sort keys" that Sort[] and Odering[] can deal with, and you sort that instead of your original list. Ordering[] will thus tell you in which sequence you should pick the elements of the original list to get the same sequence as the auxiliary list after sorting. $\endgroup$ Sep 21, 2015 at 15:47

2 Answers 2

7
$\begingroup$

Look at the Possible Issues section of the documentation for Sort: "Numeric expressions are sorted by structure as well as numerical value"

list = {1/2 (1 + Sqrt[5]), 1, 1, 1/2 (1 - Sqrt[5]), 0};

The approach recommended there to Sort by numerical value only is

sorted = Sort[list, Less]

(*  {(1/2)*(1 - Sqrt[5]), 0, 1, 1, 
   (1/2)*(1 + Sqrt[5])}  *)

Verifying numeric order

% // N

(*  {-0.618034, 0., 1., 1., 1.61803}  *)

Or equivalently,

sorted === Sort[list, #1 < #2 &]

(*  True  *)

Or use SortBy

sorted === SortBy[list, N]

(*  True  *)
$\endgroup$
6
$\begingroup$

Not a bug. The docs: "Sort usually orders expressions by putting shorter ones first, and then comparing parts in a depth‐first manner."

You want SortBy[list,N], I think. For more complex cases, use Ordering[] to get a list of indexes and use that to reorder the original list:

Ordering@N@list
list[[%]]

Perhaps you should consider the option of handing Sort[] your own ordering predicate. Just use any pure function whatsoever which works on #1 and #2 and returns True if #1 comes before #2 in your desired sort order, or False otherwise:

peopleAndAges={{"Felix",50},{"Max",19},{"Sophie",22}};
CompareByName[{n1_String,_},{n2_String}]:=(ToLowerCase@n1 <= ToLowerCase@n2)
CompareByAge[{_,a1_},{_,a2_}]:=(a1 >= a2)

Sort[peopleAndAges,CompareByAge]
$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.