Have the key
function return a tuple, with items in decreasing order of priority:
table.sort(reverse=True, key=lambda team: (Team.getPoints(team),
Team.getGoalDifference(team),
Team.getName(team))
Alternately, you could remember a factoid from algorithms 101, and make use of the fact .sort()
is a stable sort, and thus doesn't change the relative order of items in a list if they compare as equal. This means you can sort three times, in increasing order of priority:
table.sort(reverse=True, key=Team.getName)
table.sort(reverse=True, key=Team.getGoalDifference)
table.sort(reverse=True, key=Team.getPoints)
This will be slower, but allows you to easily specify whether each step should be done in reverse
or not. This can be done without multiple sorting passes using cmp_to_key()
, but the comparator function would be nontrivial, something like:
def team_cmp(t1, t2):
for key_func, reverse in [(Team.getName, True),
(Team.getGoalDifference, True),
(Team.getPoints, True)]:
result = cmp(key_func(t1), key_func(t2))
if reverse: result = -result;
if result: return result
return 0
table.sort(functools.cmp_to_key(team_cmp))
(Disclaimer: the above is written from memory, untested.) Emphasis is on "without multiple passes", which does not necessarily imply "faster". The overhead from the comparator function and cmp_to_key()
, both of which are implemented in Python (as opposed to list.sort()
and operator.itemgetter()
, which should be part of the C core) is likely to be significant.
As an aside, you don't need to create dummy functions to pass to the key
parameters. You can access the attribute directly, using:
table.sort(key=lambda t: t.points)
or the attrgetter
operator wrapper:
table.sort(key=attrgetter('points'))