python-3.xlistsortingtuplesstable-sort

Sorting tuples in python and keeping the relative order


Input = [("M", 19), ("H", 19), ("A", 25)]

Output =[("A", 25), ("M" ,19), ("H", 19)]

It should sort alphabetically but when the second value is equal then it should remain in place without changing their respective places. Here M and H both have value as 19 so it is already sorted.


Solution

  • You could group the items by the second value of each tuple using itertools.groupby, sort groupings by the first item in each group, then flatten the result with itertools.chain.from_iterable:

    from operator import itemgetter
    from itertools import groupby, chain
    
    def relative_sort(Input):
        return list(
            chain.from_iterable(
                sorted(
                    (
                        tuple(g)
                        for _, g in groupby(
                            sorted(Input, key=itemgetter(1)), key=itemgetter(1)
                        )
                    ),
                    key=itemgetter(0),
                )
            )
        )
    

    Output:

    >>> relative_sort([("M", 19), ("H", 19), ("A", 25)])
    [('A', 25), ('M', 19), ('H', 19)]
    >>> relative_sort([("B", 19), ("B", 25), ("M", 19), ("H", 19), ("A", 25)])
    [('B', 19), ('M', 19), ('H', 19), ('B', 25), ('A', 25)]
    >>> relative_sort([("A", 19), ("B", 25), ("M", 19), ("J", 30), ("H", 19)])
    [('A', 19), ('M', 19), ('H', 19), ('B', 25), ('J', 30)]