Sort by multiple conditions in python

I am new to programming and now I am writing a league table in python. I would like to sort my league by the first points, and if there are two teams with the same points, I would like to sort them by the goal difference, and if they have the same difference in the fields, I would like to sort by name.

The first condition is quite simple and works as follows:

table.sort(reverse=True, key=Team.getPoints) 

How to insert the following two conditions?

+7
source share
3 answers

Ask the key function to return a tuple with elements in descending order of priority:

 table.sort(reverse=True, key=lambda team: (Team.getPoints(team), Team.getGoalDifference(team), Team.getName(team)) 

Alternatively, you can recall the factoid from 101 algorithms and use the fact .sort() is a stable sort and, therefore, does not change the relative order of the items in the list if they are compared as equal. This means that you can sort three times in order of increasing 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 makes it easy to determine whether each step should be performed in reverse or not. This can be done without several sorting passes using cmp_to_key() , but the comparator function would be nontrivial, for example:

 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, unverified.) The emphasis is on "without multiple passes", which does not necessarily mean "faster." The overhead of the comparator function and cmp_to_key() , both of which are implemented in Python (unlike list.sort() and operator.itemgetter() , which should be part of the C core), are likely to be significant.

As an aside, you do not need to create dummy functions in order to go to the key parameters. You can access the attribute directly using:

 table.sort(key=lambda t: t.points) 

or attrgetter operator shell:

 table.sort(key=attrgetter('points')) 
+10
source

First, sort the list by name, and then sort by the difference in the invoice again. Python sort is stable, which means that it will keep the order of elements compared to equals.

+4
source

The Python Timsort sorting algorithm, which, as ACEfanatic02 points out, is stable , which means that the order is preserved. This link has a nice visual explanation of how it works.

0
source

All Articles