pythonsortingstability

on Python's "sorted" method being stable or not


I am trying to sort a list array using the following code:

from operator import itemgetter

data=[['Japan',0],['Japan',36],['Japan',21],['Germany',7]]
for line in data: print(line)
print('---')
sort1=sorted(data,key=itemgetter(0))
for line in sort1: print(line)
print('---')
sort1=sorted(sort1,key=itemgetter(1))
for line in sort1: print(line)

in Python 3.9.5 and I find it not to be working as I expect:

['Japan', 0]
['Japan', 36]
['Japan', 21]
['Germany', 7]
---
['Germany', 7]
['Japan', 0]
['Japan', 36]
['Japan', 21]
---
['Japan', 0]
['Germany', 7]
['Japan', 21]
['Japan', 36]

The first call to sorted did move "Germany" first without touching the rest; but the second, that I expected to reorder the "Japan" lines by leaving "Germany" on top, did not: it reordered everything instead on the second field.

I have been reading literature and answers all over the internet for hours, found extremely many tutorials on how to do that, for example here at point 29: Sorting a Python list by two fields and it seems that I am doing exactly the same thing. But clearly not.


Solution

  • When you use sort() or sorted(), it'll sort the list based on the key you provided it, and it'll keep ties in the same order it initially was. So, if you want to sort based on multiple parameters, sort it by the last tiebreaker first.

    ['Japan', 0]
    ['Japan', 36]
    ['Japan', 21]
    ['Germany', 7]
    ---First sorting by the number (lower priority):
    ['Japan', 0]
    ['Germany', 7]
    ['Japan', 21]
    ['Japan', 36]
    ---Then sorting by the country (ties keep their order):
    ['Germany', 7]
    ['Japan', 0]
    ['Japan', 21]
    ['Japan', 36]