Skip to content
VLSI Mentor

Python Part I · Module 5 · Lists

Sorting and Ordering Results

A list of results in the order the tests happened to finish is not a report. Put them in order and the same data becomes readable — failures grouped together, the slowest test at the top, names alphabetical so a reader can find one. Python gives you two ways to do that, and choosing between them is the real content of this chapter, because one of them changes the list you already have and the other leaves it alone and builds a new one. That is the mutable-versus-new tension from Chapter 5.3 showing up as an actual decision for the first time. The chapter also covers the ordering rule that makes people think sorting is broken the first time they meet it.

Foundation13 min readPythonPart IFundamentalsListsSorting

Part I · Module 5 · Chapter 5.5 · Sorting and Ordering Results

1. sort(): Put This List in Order

sort is a list method, and like every mutating method in Chapter 5.3 it changes the list you already have. Before and after:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
tests = ["reset", "burst", "smoke"]
print(tests)
tests.sort()
print(tests)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
['reset', 'burst', 'smoke']
['burst', 'reset', 'smoke']

The same list, now alphabetical. No new list was made and nothing needed assigning.

Which means the Chapter 5.3 trap applies in full:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
t = ["b", "a"]
print(t.sort())
print(t)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
None
['a', 'b']

sort() evaluates to None, exactly as append did, and for the same reason — the change already happened to your list. So tests = tests.sort() sets tests to None, silently. If that rule is not yet automatic, Chapter 5.3 Section 5 is where it is explained.

Numbers sort numerically, which is worth confirming rather than assuming:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
seeds = [4210, 77, 9124]
seeds.sort()
print(seeds)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
[77, 4210, 9124]

77 first. Had these been the strings "4210", "77" and "9124" the answer would have been different, because text is compared character by character — "77" starts with 7 and "4210" starts with 4, so "4210" would come first. The type of your elements decides the order you get.

2. Descending Order

sort takes an option for reversing the result:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
runtimes = [12.4, 8.7, 19.2]
runtimes.sort(reverse=True)
print(runtimes)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
[19.2, 12.4, 8.7]

reverse=True inside the parentheses is a named option — the name says which setting you are changing. You have seen the shape before in print() and split(); this is the first time the name matters for reading the line. Written out, sort(reverse=True) says sort, with reversing switched on.

Slowest first is the usual thing you want from a runtime column, so this is the option you will reach for most.

3. Why "APB" Sorts Before "burst"

Here is the result that makes people think sorting is broken:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
mixed = ["smoke", "Reset", "burst", "APB"]
mixed.sort()
print(mixed)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
['APB', 'Reset', 'burst', 'smoke']

Both capitalised names came first, and within each group the order is alphabetical. That is not a bug and it is not random.

Sorting text compares characters, using the same < you met in Chapter 3.4. And on characters, every capital letter comes before every lowercase one:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
print("A" < "a")
print("Z" < "a")
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
True
True

Even "Z" is less than "a". So a sort puts everything beginning with a capital ahead of everything beginning with a lowercase letter, and the result looks alphabetically scrambled to a reader who was thinking about words rather than characters.

4. sorted(): Order Without Changing Anything

sorted() is a built-in function, not a method, and that difference in notation reflects a real difference in behaviour. It leaves your list exactly as it was and hands back a new list in order:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
original = ["reset", "burst", "smoke"]
ordered = sorted(original)
print(original)
print(ordered)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
['reset', 'burst', 'smoke']
['burst', 'reset', 'smoke']

Two lists now exist. original is untouched — in the order the results arrived — and ordered is a new list with the same elements arranged.

That is exactly the len() situation from Chapter 4.6 again: a built-in function that works on many kinds of value, written with the value in the parentheses. Which is why it also works on a string, and tells you something about what it returns:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
print(sorted("cab"))
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
['a', 'b', 'c']

A list, not a string. sorted() always produces a list, whatever it was given.

Choosing between them

This is the decision the chapter is really about, and it is not a style preference:

tests.sort()sorted(tests)
What it isa list methoda built-in function
Your list afterwardsreorderedunchanged
Evaluates toNonea new sorted list
Correct usagetests.sort() on its own lineordered = sorted(tests)
Works onlistslists, strings, and more

5. Duplicates Survive

Sorting rearranges; it never removes:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
s = ["PASS", "FAIL", "PASS"]
s.sort()
print(s)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
['FAIL', 'PASS', 'PASS']

Three elements before, three after. Both "PASS" entries are still there, now adjacent. That is the behaviour you want for results data — two tests that both passed are two facts, not one.

6. reverse() Is Not Sorting

There is also a reverse() method, and it is easy to confuse with the reverse=True option from Section 2. They do different things.

reverse() flips the list end to end, in whatever order it currently is:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
tests2 = ["smoke", "reset", "burst"]
tests2.reverse()
print(tests2)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
['burst', 'reset', 'smoke']

That happens to look alphabetical, which is a coincidence of this example. Try it on a list that is not already ordered and the point is clear:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
t3 = ["b", "c", "a"]
t3.reverse()
print(t3)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
['a', 'c', 'b']

Not sorted — just backwards. reverse() never compares anything; it only turns the list around.

Like the other mutating methods, it changes the list and returns nothing useful:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
t4 = ["a", "b"]
print(t4.reverse(), t4)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
None ['b', 'a']

7. What You Cannot Do Yet

Two real limitations, and it is better to name them than to leave you to discover them.

Case-insensitive sorting. Section 3 showed that ["smoke", "Reset"] sorts capitals first. The fix is to tell sort to compare something other than the element itself — the lowercased version of it — and that means handing sort a small piece of code to apply to each element. Code you can pass around as a value is a function, and Module 11 is where functions are built.

Sorting by something other than the element. Given a list of rows like ["smoke", "PASS", 12.4], sorting by runtime means comparing the third item of each row rather than the row itself. Same tool, same module.

8. Broken on Purpose

Sorting a list of mixed types. Ordering means comparing, and Python will not invent an order between a number and a piece of text:

Azvya Education Pvt. Ltd.VLSI Mentor
BROKEN ON PURPOSE
x = ["smoke", 4210]
x.sort()
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
TypeError: '<' not supported between instances of 'int' and 'str'

Read the message literally: to sort, Python needed to ask whether one element is less than another, and there is no answer to 4210 < "smoke". Chapter 3.4 made exactly this point about comparing values of different types; sorting is where it becomes a practical limit.

This is the concrete reason Chapter 5.1 argued that most useful lists hold one kind of thing. A list of runtimes sorts; a list of a name, a status and a runtime does not.

Assigning the result of sort(). The trap from Chapter 5.3, applied here:

Azvya Education Pvt. Ltd.VLSI Mentor
BROKEN ON PURPOSE
t = ["b", "a"]
t = t.sort()
print(t)
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
None

No error, and t is now None. The list was sorted correctly and then thrown away.

9. Predict, Run, Observe

Predict every line before reading on.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
names = ["reset", "APB", "smoke"]
ordered = sorted(names)
print(names)
print(ordered)
names.sort()
print(names)
print(names.sort())
nums = [3, 1, 2]
nums.sort(reverse=True)
print(nums)
nums.reverse()
print(nums)

The verified output:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
['reset', 'APB', 'smoke']
['APB', 'reset', 'smoke']
['APB', 'reset', 'smoke']
None
[3, 2, 1]
[1, 2, 3]

The first line is the point of sorted(): names is unchanged after it. The second shows "APB" first, because capitals sort ahead of lowercase — Section 3.

The third line shows names now reordered, because sort() changed it. The fourth is None, because that is what sort() evaluates to.

The last pair is worth checking carefully. nums.sort(reverse=True) gives [3, 2, 1] — sorted, descending. Then nums.reverse() flips that to [1, 2, 3]. The second call did not sort anything; it turned the already-descending list around, which in this case happens to produce ascending order.

10. Exercises

Exercise 1 — in place or new. For runtimes = [12.4, 8.7, 19.2], write the line that puts runtimes itself in order, and separately the line that leaves it alone and gives you an ordered copy called ranked. Print runtimes after each to prove the difference.

Exercise 2 — predict the order. Without running anything, give the sorted result of each, then verify: (a) ["b", "a", "c"] (b) ["B", "a", "C"] (c) [10, 9, 100] (d) ["10", "9", "100"] (e) ["PASS", "FAIL", "PASS"]

Explain (c) and (d) — the same-looking data gives different orders.

Exercise 3 — the None trap. This prints None. Say which three steps produced it and fix it with the smallest change:

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
tests = ["reset", "burst"]
tests = tests.sort()
print(tests)

Exercise 4 — descending. Write two different expressions that both give the runtimes largest-first, one using sort and one using sorted. Say which you would use if the original arrival order still mattered.

Exercise 5 — sort or reverse. A colleague wants ["c", "a", "b"] in alphabetical order and writes items.reverse(). Say what they actually get, why, and give the line they meant.

Exercise 6 — the mixed list. Explain in two sentences why ["smoke", 4210].sort() raises, quoting the operator named in the error, and say what that tells you about how sorting works.

Exercise 7 — which tool. For each, name sort() or sorted() and give one sentence of justification: (a) print an alphabetical index of test names, keeping the run order for a later report (b) put a working list of jobs into a fixed order before processing (c) show the five slowest runtimes without disturbing the results list

11. Summary

  • tests.sort() orders the list in place and evaluates to None. tests = tests.sort() sets tests to None.
  • sorted(tests) leaves your list alone and returns a new ordered list. It is a built-in function, like len(), and always returns a list.
  • Choose by whether the original order still matters. Sorting in place discards it permanently.
  • sort(reverse=True) gives descending order — the usual choice for a runtime column.
  • Text sorts by character order, and every capital comes before every lowercase letter. "Z" < "a" is True, so "APB" sorts before "burst".
  • Numbers sort numerically; strings of digits sort as text. [77, 4210] and ["77", "4210"] order differently.
  • Duplicates are kept, moved next to each other.
  • reverse() flips the list; it does not order it. It is a different thing from the reverse=True option.
  • Sorting mixed types raises TypeError: '<' not supported between instances of ..., because ordering requires comparing.
  • Case-insensitive sorting and sorting by a field need the key option, which takes a function — Module 11.

Ordering arranges what is already in a list. The next chapter puts two lists together.

Where this fits

Part of the Python curriculum.