在python中按多个条件排序 [英] Sorting by multiple conditions in python

查看:123
本文介绍了在python中按多个条件排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是编程新手,现在我正在用python编写联赛表.我想按积分排名我的联赛,如果有两支球队的积分相同,我想按进球数对他们进行排序,如果他们的进球数相同,我想按名称进行排序.

第一个条件很容易,并且可以通过以下方法进行工作:

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

如何插入以下两个条件?

解决方案

使key函数返回一个元组,且其项的优先级从高到低:

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

或者,您可以记住算法101中的一个类事实,并利用事实.sort() stable 排序,因此,如果出现以下情况,则不会更改列表中项目的相对顺序他们比较相等.这意味着您可以按优先级从高到低的顺序进行三遍排序:

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

(免责声明:以上内容是从内存中写入的,未经测试.)重点是没有多次通过",这不一定意味着更快".比较器函数和cmp_to_key()的开销很可能是巨大的.比较器函数和cmp_to_key()都是用Python实现的(与list.sort()operator.itemgetter()相对,后者应该是C内核的一部分).

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

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

attrgetter 运算符包装:

table.sort(key=attrgetter('points'))

I am new to programming and right now i'm writing a league table in python. I would like to sort my league by first points, and if there are two teams with the same points I would like to sort them by goal difference, and if they have the same goal difference i would like to sort by name.

The first condition is pretty easy and is working by the following:

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

how do I insert the two following conditions?

解决方案

Have the key function return a tuple, with items in decreasing order of priority:

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

Alternately, you could remember a factoid from algorithms 101, and make use of the fact .sort() is a stable sort, and thus doesn't change the relative order of items in a list if they compare as equal. This means you can sort three times, in increasing order of priority:

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

This will be slower, but allows you to easily specify whether each step should be done in reverse or not. This can be done without multiple sorting passes using cmp_to_key(), but the comparator function would be nontrivial, something like:

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

(Disclaimer: the above is written from memory, untested.) Emphasis is on "without multiple passes", which does not necessarily imply "faster". The overhead from the comparator function and cmp_to_key(), both of which are implemented in Python (as opposed to list.sort() and operator.itemgetter(), which should be part of the C core) is likely to be significant.

As an aside, you don't need to create dummy functions to pass to the key parameters. You can access the attribute directly, using:

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

or the attrgetter operator wrapper:

table.sort(key=attrgetter('points'))

这篇关于在python中按多个条件排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆