You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中使用__cmp__与__lt__排序对象列表失败求助

如何正确为自定义Vertice类实现排序?

我帮你找出问题啦!你的代码排序失效主要有两个核心原因,咱们一步步拆解解决:

问题根源

  1. Python3已废弃__cmp__方法:你写的__cmp__在Python3里不会被sort()调用,这个方法是Python2的遗留产物,完全起不到作用,可以直接删掉。
  2. __lt__和__gt__返回值错误:这两个比较魔术方法需要返回布尔值(True/False),但你返回的是整数(-1、1、0)。Python会把非零整数视为True,这直接打乱了排序的判断逻辑,导致排序结果混乱。

修正后的代码实现

根据你“先按coordenada_x排序,再按coordenada_y排序”的需求,我们只需要正确实现__lt__方法即可(sort()默认依赖__lt__来确定元素顺序):

class Vertice:
    def __init__(self, coordenada_x, coordenada_y):
        self.coordenada_x = coordenada_x
        self.coordenada_y = coordenada_y
    
    def __str__(self):
        return "Vértice ({},{})".format(self.coordenada_x, self.coordenada_y)
    
    def __add__(self, otro_vertice):
        vertice_resultado = Vertice(self.coordenada_x + otro_vertice.coordenada_x, self.coordenada_y + otro_vertice.coordenada_y)
        return vertice_resultado
    
    # 核心:正确实现__lt__,先按x升序,x相同则按y升序
    def __lt__(self, otro_vertice):
        if self.coordenada_x != otro_vertice.coordenada_x:
            return self.coordenada_x < otro_vertice.coordenada_x
        else:
            return self.coordenada_y < otro_vertice.coordenada_y

import random

def main():
    lista = []
    for i in range(0,10):
        a = random.randint(1,99)
        b = random.randint(1,99)
        lista.append(Vertice(a,b))
    
    print("排序前:")
    for elemento in lista:
        print(elemento)
    
    print("\n排序后:")
    lista.sort()
    for elemento in lista:
        print(elemento)

main()

额外优化:自动生成所有比较方法

如果你需要支持>、<=、>=等其他比较操作,可以用functools.total_ordering装饰器,只需要实现__lt__和__eq__,其他比较方法会自动生成,代码更简洁:

from functools import total_ordering
import random

@total_ordering
class Vertice:
    def __init__(self, coordenada_x, coordenada_y):
        self.coordenada_x = coordenada_x
        self.coordenada_y = coordenada_y
    
    def __str__(self):
        return "Vértice ({},{})".format(self.coordenada_x, self.coordenada_y)
    
    def __add__(self, otro_vertice):
        vertice_resultado = Vertice(self.coordenada_x + otro_vertice.coordenada_x, self.coordenada_y + otro_vertice.coordenada_y)
        return vertice_resultado
    
    def __lt__(self, otro_vertice):
        if self.coordenada_x != otro_vertice.coordenada_x:
            return self.coordenada_x < otro_vertice.coordenada_x
        else:
            return self.coordenada_y < otro_vertice.coordenada_y
    
    def __eq__(self, otro_vertice):
        return (self.coordenada_x == otro_vertice.coordenada_x) and (self.coordenada_y == otro_vertice.coordenada_y)

def main():
    lista = []
    for i in range(0,10):
        a = random.randint(1,99)
        b = random.randint(1,99)
        lista.append(Vertice(a,b))
    
    print("排序前:")
    for elemento in lista:
        print(elemento)
    
    print("\n排序后:")
    lista.sort()
    for elemento in lista:
        print(elemento)

main()

关于排序方向

  • 如果需要降序排序,你可以直接在调用sort()时加上参数:lista.sort(reverse=True),不需要修改__lt__方法。
  • 或者也可以把__lt__里的<改成>,直接实现降序的比较逻辑。

内容的提问来源于stack exchange,提问作者user1746636

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:16:10