为什么不对结果进行排序?

2024-09-29 19:32:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我面临着调试这段代码的问题。给定一个玩家对象数组,编写一个比较器,按照分数递减的顺序对它们进行排序。如果有一个或多个玩家有相同的分数,按名字的字母顺序升序排列这些玩家。为此,必须创建一个Checker类来实现Comparator接口,然后编写一个int compare(Player a,Player b)方法来实现比较器.compare(T o1,T o2)法。你知道吗

from functools import cmp_to_key
class Player:
    def __init__(self, name, score):
        self.name = name
        self.score = score
    def __repr__(self):
        return repr((self.name, self.score))

    def comparator(a, b):
        if a.score>b.score:
            return True
        if(a.score==b.score):
            return a.name<b.name
        return False



n = int(input())
data = []
for i in range(n):
    name, score = input().split()
    score = int(score)
    player = Player(name, score)
    data.append(player)

data = sorted(data, key=cmp_to_key(Player.comparator))
for i in data:
    print(i.name, i.score)
Input:
5
amy 100
david 100
heraldo 50
aakansha 75
aleksa 150

Expected Output:
aleksa 150
amy 100
david 100
aakansha 75
heraldo 50

Actual Output:
amy 100
david 100
heraldo 50
aakansha 75
aleksa 150

Tags: keynameselfdatareturndef玩家int
3条回答

我只是把比较器函数替换成这个。成功了。你知道吗

def comparator(a, b):
        if a.score > b.score:
            return -1
        elif a.score < b.score:
            return 1
        elif a.score == b.score:
            if a.name > b.name:
                return 1
            elif a.name < b.name:
                return -1
            else:
                return 0

你不需要一个comparator函数(或者如果你想要的话,它可以简单得多),因为Python会分层比较元组。你知道吗

data = sorted(data, key=lambda p:(-p.score,p.name))

根据cmp_to_keyhttps://docs.python.org/2/library/functools.html#functools.cmp_to_key)的文档,您的比较函数是错误的:

A comparison function is any callable that accept two arguments, compares them, and returns a negative number for less-than, zero for equality, or a positive number for greater-than.

您的comparator函数返回布尔值True或False,您可以通过以下方式将其重写为所需的规范:

def comparator(a, b):
    lhs = (-a.score, a.name)  # negating score to sort descending
    rhs = (-b.score, b.name)
    if lhs == rhs:
        return 0
    elif lhs < rhs:
        return -1
    else:
        return 1

更新: 正如@ShadowRanger指出的,比较函数可以更有效地编写为:

def comparator(a, b):
    lhs = (-a.score, a.name)  # negating score to sort descending
    rhs = (-b.score, b.name)
    return lhs > rhs or -(lhs < rhs)

为了理解为什么/如何工作,您需要知道在Python中boolint的子类(和子类型),并且False被定义为0True被定义为1(来自PEP-0285):

False = int.__new__(bool, 0)
True = int.__new__(bool, 1)

这意味着你可以做一些“奇怪”的事情,比如:

>>> True + 1
2
>>> -True
-1
>>> -False
0

所以如果lhs > rhs(我们应该返回1),那么标记的部分

return lhs > rhs or -(lhs < rhs)
       ^^^^^^^^^

True1),并且or的右边不会被执行,我们根据需要返回1。你知道吗

如果lhs < rhs(我们应该返回-1),那么上面标记的部分将是False,因为False or x == x我们剩下:

return -(lhs < rhs)
         ^^^^^^^^^

其中标记的部分是True

return -(True)

从上面看-True-1,这就是我们想要返回的这个例子。你知道吗

如果lhs == rhs(我们应该返回0),我们得到

return False or -(False)

False or x仍然是x,因此剩下:

return -(False)

从上面看,是0。你知道吗

注意:在Python中看到这些类型的函数已经不常见了,现在您通常在类中定义__lt____eq__,并使用total_ordering中的functoolshttps://docs.python.org/3.3/library/functools.html#functools.total_ordering)修饰符。你知道吗

相关问题 更多 >

    热门问题