Suppose you have a list of animals:
>>> animals=['aarvark','zebra','giraffe','bear','dog','cat','badger','ant']
Sorted lexicographically, or in alphabetical order, aardvark is sorted before ant and both before zebra:
>>> sorted(animals)
['aarvark', 'ant', 'badger', 'bear', 'cat', 'dog', 'giraffe', 'zebra']
Now suppose your 10 year old tells you I want all animals that start with 'b' sorted first, then 'z' then alphabetically.
With a key function, this is trivial to accomplish:
>>> lookup=['b','z']
>>> key_func=lambda s: (lookup.index(s[0]),s) if s[0] in lookup else (len(lookup),s)
>>> sorted(animals, key=key_func)
['badger', 'bear', 'zebra', 'aarvark', 'ant', 'cat', 'dog', 'giraffe']
Before the key function was added to Python sorting routines, the common approach to a problem like this was called Decorate, Sort, Undecorate and can be seen here:
>>> ts=sorted([(lookup.index(s[0]),s) if s[0] in lookup else (len(lookup), s) for s in animals])
>>> ts
[(0, 'badger'), (0, 'bear'), (1, 'zebra'), (2, 'aarvark'), (2, 'ant'), (2, 'cat'), (2, 'dog'), (2, 'giraffe')]
>>> [t[1] for t in ts]
['badger', 'bear', 'zebra', 'aarvark', 'ant', 'cat', 'dog', 'giraffe']
(BTW: This example is way easier and faster if you use a dict instead of a list:
>>> lookup={'b':0, 'z':1}
>>> sorted(animals, key=lambda s: (lookup.get(s[0], len(lookup)),s))
['badger', 'bear', 'zebra', 'aarvark', 'ant', 'cat', 'dog', 'giraffe']
That is the right way but your question involved list lookup...)
Key functions allow you to modify how the sort order is interpreted. For another example, consider if you wanted to sort by integers found in the sort strings and then alphabetically.
Here is the list:
>>> nl=['zebra65','ant101','bear5','no num', '2 num first', 's with 1 and 2']
If you just use the default, it comes out ASCIIbetically:
>>> sorted(nl)
['2 num first', 'ant101', 'bear5', 'no num', 's with 1 and 2', 'zebra65']
With a simple regex and key function, you can find all the numbers and form a tuple for sorting by number then the string:
import re
def find_n(s):
ml=re.findall(r'(\d+)', s)
if ml:
return tuple(map(int, ml))+(s,)
return (0,s)
>>> sorted(nl, key=find_n)
['no num', 's with 1 and 2', '2 num first', 'bear5', 'zebra65', 'ant101']