自定义排序一个元组列表

3

我几天前才开始学习Python,并希望在其中实现我的小项目。我需要按照数字值的降序,对包含一个字符串和一个整数的列表进行排序,但如果数字对于多个元组相同,则按字母顺序排序。所以我有一个列表,比如:

tuples = [('ggg', 5), ('aaa', 5), ('bbb', 6), ('zzz', 6)]
tuples.sort(key=lambda score: score[1], reverse=True)

这将返回:

[('bbb', 6), ('zzz', 6), ('ggg', 5), ('aaa', 5)]

我希望你能帮我翻译以下内容:但我想要得到的是:
[('bbb', 6), ('zzz', 6), ('aaa', 5), ('ggg', 5)]

在Java中,我刚刚为自定义元组实现了一个比较器:
class Pair {
    public final String s;
    public final Integer i;

    public Pair(String s, Integer i) {
        this.s = s;
        this.i = i;
    }
}

class PairComparator implements Comparator<Pair> {

    @Override
    public int compare(Pair p1, Pair p2) {
        int c = p1.i.compareTo(p2.i);
        return (c == 0) ? p1.s.compareTo(p2.s) : c * (-1);
    }
}

但我不确定如何在 Python 的一个 lambda 表达式中完成这个任务。


你想要在数字上按降序排列,然后在字母上按升序排列吗? - PM 2Ring
Python 2 允许为 sort(和 max & min)提供自定义比较函数参数,但这在 Python 3 中已被淘汰,因为它效率较低:自定义键函数只需要为每个键调用一次,但自定义比较函数会在每次比较时都被调用。 - PM 2Ring
在Python 3中,可以实现自定义比较:创建一个实现丰富比较方法的类。另一方面,Python内置的sort(也称为Timsort)是稳定的,因此当您具有复杂的排序要求时,可能只需使用不同的键多次对列表进行排序,而无需使用自定义比较。 - PM 2Ring
3个回答

3
也许最简单的方法是让key返回一个元组,并将分数乘以-1。例如:
>>> tuples.sort(key=lambda x: (-x[1], x[0]))
>>> tuples
[('bbb', 6), ('zzz', 6), ('aaa', 5), ('ggg', 5)]

这将按降序排列整数,然后按升序排列字符串。


如果我发表评论,我应该知道我会被“忍者”抢先。 :) - PM 2Ring
1
这种情况发生在我身上的次数已经数不清了 :-) - Alex Riley

1
你可以根据数字的负形进行排序,不使用reverse=True
>>> >>> tuples.sort(key=lambda x:(-x[1],x[0]))
>>> tuples
[('bbb', 6), ('zzz', 6), ('aaa', 5), ('ggg', 5)]

1
如果在键中不指定 x[0],它将被忽略,并且由于Timsort是稳定的,基于 x[0] 的项目排序不会改变。请在 [('bbb', 6), ('zzz', 6), ('aaa', 5), ('xxx', 5), ('ggg', 5)] 上尝试您的代码。 - PM 2Ring
@PM2Ring 噢,我忘记了 lambda,谢谢提醒。 - Mazdak

0

另一个选项是使用操作符模块函数operator.itemgetter()两次对它们进行排序。我们首先按升序排序第一个元素,然后按降序排序第二个元素(尽管这种方法效率较低)。

In [1]: from operator import itemgetter

In [2]: tuples = [('ggg', 5), ('aaa', 5), ('bbb', 6), ('zzz', 6)]

In [3]: tuples.sort(key=itemgetter(0)) # [('aaa', 5), ('bbb', 6), ('ggg', 5), ('zzz', 6)]

In [4]: tuples.sort(key=itemgetter(1), reverse=True) # sort by 2nd element in descending order

In [5]: tuples
Out[5]: [('bbb', 6), ('zzz', 6), ('aaa', 5), ('ggg', 5)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接