Skip to main content

Ordering a Collection

Sorting means putting the elements of a collection in a certain order.

Some types have a natural order. Numbers are ordered by value: 1 comes before 2. Strings are ordered alphabetically: "four" comes before "one". For everything else, or when you want a different order, you give a custom order with a key function: a function that turns one element into the value it should be sorted by.

Python sorts lists in two ways:

  • sorted(s) returns a new sorted list and leaves the original as it was. It works on any iterable.
  • s.sort() sorts the list in place: the original order is gone.

Both take the same two keyword arguments: key= (the key function) and reverse=True for descending order. Many languages sort with a compare function that looks at two elements; Python instead asks for a key of one element and compares the keys. Almost every compare function you would write becomes a shorter key function, for example key=len to sort by length.

The examples below use the words one, two, three, four.


Natural Order

Natural order is the order a type has on its own: numbers by value, strings letter by letter.

sorted(words) gives a new list in natural order. For descending order you do not sort twice: pass reverse=True and the new list comes out turned around.

Tuples also have a natural order: Python compares them position by position and the first difference decides. That gives your own data an order for free. A version number stored as the tuple (major, minor) is compared major first, and only when the majors are equal does minor decide — exactly the reusable comparison you would otherwise write by hand.

Sorted copy

sorted() makes a new, alphabetically sorted list. The original words list is printed afterwards to show it did not change.

Prompt
Take the words one, two, three, four. Make a new list sorted in natural (alphabetical) order with sorted(), so the original list is not changed. Print the sorted list, then print the original list.
Output: complete Python program
Sorted copy

Sorted descending

reverse=True makes sorted() return the new list in descending order, so the words go from "two" down to "four".

Prompt
Take the words one, two, three, four. Use sorted() with reverse=True to get a new list in descending alphabetical order. Print the result.
Output: complete Python program
Sorted descending

A type with its own order

A version is the tuple (major, minor). Tuple comparison looks at major first; only when the majors are equal does minor decide. (1, 2) > (1, 3) asks "is version 1.2 greater than 1.3?" and prints False; (2, 0) > (1, 5) prints True.

Prompt
Store version numbers as (major, minor) tuples. Using natural tuple comparison, print whether version 1.2 is greater than 1.3, then whether 2.0 is greater than 1.5.
Output: complete Python program
A type with its own order

Custom Orders

A custom order is any order you describe with a key function.

Pass it as key=: Python calls the function once per element and sorts the elements by what it returns. Python's sort is stable: elements whose keys are equal always keep their original order. You never need a separate stable sort, for example when sorting words by length.

Sorting by one property of each element is the everyday case: key=len sorts by length, and a lambda picks out anything else, such as a word's last letter.

For descending order add reverse=True. It flips the comparison of the keys, and equal elements still keep their original order.

To sort by one thing and then by another, return a tuple from the key function. Tuples compare position by position, so the second entry breaks the tie when the first one says the elements are equal.

Sort with a key function

key=len gives every word its length as the key: 3 for "aaa", 2 for "bb", 1 for "c". The smallest key comes first, so the words end up from shortest to longest. words.sort() does it in place.

Prompt
Take the words aaa, bb, c. Sort the list in place with words.sort(key=len), so shorter words come first. Print the result.
Output: complete Python program
Sort with a key function

Sort by length

The words are sorted by key=len. "one" and "two" are both 3 letters long; the stable sort keeps "one" before "two".

Prompt
Take the words one, two, three, four. Sort them by length with sorted() and key=len, so words of the same length keep their original order. Print the result.
Output: complete Python program
Sort by length

Sort by last letter, descending

w[-1] is the last letter of a word. With reverse=True the word with the largest last letter comes first: "four" (r), then "two" (o), then the two words ending in "e" in their original order.

Prompt
Take the words one, two, three, four. Sort them by their last letter in descending order: use sorted() with key=lambda w: w[-1] and reverse=True. Print the result.
Output: complete Python program
Sort by last letter, descending

Sort by length, then alphabetically

The key (len(w), w) is a tuple: the length first. When two words are equally long, the second entry — the word itself — orders them alphabetically.

Prompt
Take the words aaa, bb, c, b, a, aa, ccc. Sort them first by length and then alphabetically, using sorted() with the tuple key (len(w), w). Print the result.
Output: complete Python program
Sort by length, then alphabetically

Check Sorted Order

Sometimes you only want to know whether a list is already sorted, without sorting it.

Python has no is_sorted() function, but the check is one line: every element must be less than or equal to its right neighbour. zip(s, s[1:]) pairs each element with the next one, and all() confirms that every pair is in order. For descending order, swap the comparison: a >= b instead of a <= b.

To check the order of one property, such as a user's age, compare that property inside the check.

Ascending and descending check

all(a <= b ...) confirms that 1, 2, 3, 4 are ascending. The swapped comparison a >= b confirms that 4, 3, 2, 1 are descending.

Prompt
Check whether the numbers 1, 2, 3, 4 are in ascending order with all() over zip(ascending, ascending[1:]) and print the answer. Then check whether 4, 3, 2, 1 are in descending order with the swapped comparison a >= b, and print that answer.
Output: complete Python program
Ascending and descending check

Check order by a field

The users are Alice (24), Bob (31) and Charlie (29). The check looks only at the ages. Bob is older than Charlie, so the list is not sorted by age and the program prints False.

Prompt
Make a list of (name, age) tuples with Alice 24, Bob 31 and Charlie 29. Pull out the ages and use all() over neighbouring pairs to check whether the users are sorted by age, and print the answer.
Output: complete Python program
Check order by a field

Reverse Order

Reversing puts the last element first and the first element last.

The slice words[::-1] builds a reversed copy: the original keeps its order. words.reverse() reverses the list in place instead. There is also a built-in reversed(words): it returns an iterator that walks the list backwards without building a new one — wrap it in list() when you need a real list.

Reversed copy

The copy made by words[::-1] is printed, then the original is printed to show it is unchanged.

Prompt
Take the words one, two, three, four. Build a reversed copy with the slice words[::-1], so the original stays the same. Print the reversed copy, then print the original.
Output: complete Python program
Reversed copy

Random Order

Shuffling puts the elements in a random order.

The random module has a shuffle() function. Like words.reverse(), it works in place, so shuffle a copy made with words[:] if you still need the original.

A random.Random(seed) object with a fixed seed gives the same "random" order every time the program runs with that seed. This is useful for tests and for examples like this one. The module-level random.shuffle() has no fixed seed, so the order changes on every run.

Shuffled copy

A random.Random object with seed 25 shuffles a copy of the words. With this seed the result is ['two', 'three', 'one', 'four'] on every run.

Prompt
Take the words one, two, three, four. Create a random.Random object with seed 25. Shuffle a copy of the list made with words[:] using the object's shuffle() method. Print the shuffled copy.
Output: complete Python program
Shuffled copy