More Calculations on Lists

Classnotes for CPSC 215

Christian Jacob — February (11^th), 2002.

Sorting Lists

Sorting the standard way

We use Sort to sort elements in a list.

For a simple list of symbols, it is obvious what Sort should return:

myList = {b, e, a, d, c};

Sort[myList]

The symbol names are sorted in alphabetical order. We can test this by using more elaborate names. Names are sorted in the order they would appear in any dictionary.

anotherList = {var, xyz, bcd, aaa, a, aaaaa, abba};

Sort[anotherList]

Sorting by default

Without specifying any criterion by which to sort, Mathematica uses a default sorting. That is,
	◼ numbers are sorted in increasing order

Sort[{33, 76, 2, 6, 17}]

◼ symbols are sorted alphabetically

Sort[{var, xyz, bcd, aaa, a, aaaaa, abba}]

◼ strings are sorted alphabetically

\(Sort[{"var", "xyz", "bcd", "aaa", "a", "aaaaa", "abba"}]\)

◼ any other expressions are sorted in a "top-down / depth-first" fashion by their
	   internal (FullForm) representations:

Sort[{g[a], f[a], g[b, c], h[k], f[b], f[2], 3, 1, f*e, d + c, F[t], b, 
        a}]

{F[a], f[a]} // Sort

In the Sort command, numbers come first, then symbols, then built-in Mathematica functions, then all other expressions.

We can verify the sorting by inspecting the internal representation for each expression:

{g[a], f[a], g[b, c], h[k], f[b], f[2], 3, 1, f*e, d + c, F[t], b, a} // 
      FullForm

The function TreeForm helps to identify the structure of expressions, and derive the outcome of the sorting:

{g[a], f[a], g[b, h[c]], g[b, f[k]]} // TreeForm

{g[a], f[a], g[b, h[c]], g[b, f[k]]} // Sort

Here is a more complicated example, that involves numbers only:

{x, y} = {(2/(1 + (Sqrt[2]))), (1/(2 (-1 + (Sqrt[2]))))};

N[{x, y}]

Sort[{x, y}]

As we do not ask Mathematica to explicitly calculate the values of these two expressions, they are sorted according to their internal representations:

{x, y}

FullForm[{x, y}]

a - b // FullForm

Sort[{x, y}]

Therefore, the entry 2 is compared to (1/2)(= Rational[1,2]). We can check this by the following command which extracts all the arguments (on level 1) of x and y, respectively.

Map[Level[#, {1}] &, {x, y}]

Note: We will explain all the details of these notations for function mapping later.

TreeForm[{x, y}]

Table[Random[Integer, {-100, 100}], {20}] // Sort

Specifying a sorting criterion

The default sorting, when applied to numbers, results in a sequence of increasing numbers.

Sort[{33, 76, 2, 6, 17}]

Hence, the sorting criterion is the Less or < function, which we can specify explicitly:

Sort[{33, 76, 2, 6, 17}, Less]

Redefining the sorting criterion can, e.g., reverse the arrangement of the elements:

Sort[{33, 76, 2, 6, 17}, Greater]

Now, returning to our more complicated formulas example,

{x, y} = {(2/(1 + (Sqrt[2]))), (1/(2 (-1 + (Sqrt[2]))))};

we can first check the actual values of the two expressions:

N[{x, y}]

So, if we specify that we want them to be sorted in their numerical order (using Less), we get the desired result:

Sort[{x, y}, Less]

Sorting of nested lists

Nested lists are sorted just like any symbolic expression, following the depth-first order:

Sort[{{1, 2}, {1, 1}, {2, 3}, {2, 2}}]

TreeForm[{{1, 2}, {1, 3}}]

Lists of lists, where each sublist has the same length, are sorted the usual way:

Sort[{{b, acc}, {(Sqrt[x]), y}, {3, 1}}]

Lists with different lengths are sorted by their length:

Sort[{{(Sqrt[x]), y, a}, {2, 3, 1, 5, 4}, {b, acc}}]

Note: No sorting occurs within the sublists!