在python中对元组进行排序并保持相对顺序

时间:2020-04-16 04:37:16

标签: python-3.x list sorting tuples stable-sort

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

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

它应该按字母顺序排序,但是当第二个值相等时,它应保持在原位,而不更改其各自位置。 M和H的值均为19,因此已经被排序。

2 个答案:

答案 0 :(得分:3)

IIUC,您可以按第二个元素对元组进行分组。首先根据元组的第二个元素使用sorted将它们收集在一起,然后根据第二个元素使用groupby将它们放入列表中。这种排序将保留您已有的顺序(根据您的数据,这种排序也可能是不必要的)。

import itertools

Input = [('M', 19), ('H', 19), ('A', 25)]
sort1 = sorted(Input, key=lambda x: x[1])
grouped = []
for _, g in itertools.groupby(sort1, lambda x: x[1]):
    grouped.append(list(g))

然后根据第一个字母对这些分组的列表进行排序,最后将其“取消列出”。

sort2 = sorted(grouped, key=lambda x: x[0][0])
Output = [tup for sublist in sort2 for tup in sublist]

答案 1 :(得分:1)

您可以使用itertools.groupby按每个元组的第二个值对项目进行分组,按每个组中的第一个项目对分组进行排序,然后使用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),
            )
        )
    )

输出:

>>> 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)]