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

Sorting tuples in python and keeping the relative order

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

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

它应该按字母顺序排序,但是当第二个值相等时,它应该保留在原位而不改变它们各自的位置。 这里 M 和 H 的值都是 19,所以它已经排序了。

您可以使用 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)]

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

然后根据第一个字母对这些分组列表进行排序,最后 "unlist" 它们。

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