8

我是编程新手,现在我正在用 python 写一个排行榜。我想按第一分对我的联赛进行排序,如果有两支球队得分相同,我想按净胜球数对它们进行排序,如果它们的净胜球数相同,我想按名字排序。

第一个条件非常简单,通过以下方式起作用:

table.sort(reverse=True, key=Team.getPoints)

如何插入以下两个条件?

4

3 回答 3

14

key函数返回一个元组,其中项目按优先级降序排列:

table.sort(reverse=True, key=lambda team: (Team.getPoints(team),
                                           Team.getGoalDifference(team),
                                           Team.getName(team))

或者,您可以记住算法 101 中的一个事实,并利用该事实.sort()是一个稳定的排序,因此如果它们比较相等,则不会改变列表中项目的相对顺序。这意味着您可以按优先级升序排序 3 次:

table.sort(reverse=True, key=Team.getName)
table.sort(reverse=True, key=Team.getGoalDifference)
table.sort(reverse=True, key=Team.getPoints)

这会更慢,但允许您轻松指定是否应该完成每个步骤reverse。这可以在不使用多次排序传递的情况下完成cmp_to_key(),但是比较器函数将是不平凡的,例如:

def team_cmp(t1, t2):
    for key_func, reverse in [(Team.getName, True),
                              (Team.getGoalDifference, True),
                              (Team.getPoints, True)]:
        result = cmp(key_func(t1), key_func(t2))
        if reverse: result = -result;
        if result: return result
    return 0

table.sort(functools.cmp_to_key(team_cmp))

(免责声明:以上内容是从内存中编写的,未经测试。)重点是“没有多次通过”,这并不一定意味着“更快”。比较器函数 and 的开销可能很大cmp_to_key(),这两者都是在 Python 中实现的(与list.sort()and相反,它应该是 C 核心的一部分)。operator.itemgetter()

顺便说一句,您不需要创建虚拟函数来传递给key参数。您可以使用以下方法直接访问该属性:

table.sort(key=lambda t: t.points)

attrgetter运算符包装器:

table.sort(key=attrgetter('points'))
于 2013-01-13T00:39:39.490 回答
4

首先按名称对列表进行排序,然后再按分数差异排序。Pythonsort是稳定的,这意味着它将保留比较相等的元素的顺序。

于 2013-01-13T00:35:15.243 回答
0

Python 排序算法是Timsort,正如 ACEfanatic02 指出的那样,它是稳定的,这意味着保持顺序。这个链接有一个很好的视觉解释它是如何工作的。

于 2013-01-13T00:43:04.213 回答