Как выполнить двойную сортировку внутри массива? - PullRequest
4 голосов
/ 22 января 2011

Я не знаю, существует ли точный термин для этого типа сортировки.Вот проблема - у меня есть класс foo

class foo:
    def __init__(self,a1,a2):
        self.attrb1 = a1
        self.attrb2 = a2

    def sort(self):
        return self.attrb1 

Массив "bar" содержит объекты типа foo.Я хочу отсортировать массив в порядке убывания по двум атрибутам.Сначала по attrb1

bar.sort(key=foo.sort,reverse=True)

Затем я хочу отсортировать отсортированные элементы внутри себя по attrb2.Итак, для двух элементов foo1 и foo2 в массиве мы имеем -

foo1 > foo2 
if foo1.attrb1 > foo2.attrb1
elif foo1.attrb1 == foo2.attrb1
foo1.attrb2 > foo2.attrb2

Как я могу это сделать?

Ответы [ 4 ]

7 голосов
/ 22 января 2011
bar.sort(key=lambda x: (x.attrb1, x.attrb2), reverse=True)

И вам не нужно определять foo.sort

2 голосов
/ 22 января 2011

Вы уже используете классы, поэтому просто реализуйте __lt__:

class foo:
    def __init__(self,a1,a2):
        self.attrb1 = a1
        self.attrb2 = a2

    # just for convenience in `__lt__`
    def defaultorder(self):
        return self.attrb1, self.attrb2

    # answers `self < other`, used by the sorting algorithm
    def __lt__(self, other):
        return self.defaultorder() < other.defaultorder()

bar.sort(reverse=True)
1 голос
/ 22 января 2011

Вы также можете сделать это без лямбды (что мне лично не нравится):

import operator 
bar.sort(key=operator.attrgetter("attrb1","attrb2"))

operator.attrgetter работает так:

a = foo(3,4)
b = operator.attrgetter("attrb1","attrb2")(a)
print(b) #  You get (3,4)
1 голос
/ 22 января 2011

Сортировка уже сделайте это, если у вас есть кортеж значений.Если вы измените метод sort для возврата кортежа:

 class foo:
    def __init__(self,a1,a2):
        self.attrb1 = a1
        self.attrb2 = a2

    def sort(self):
        return self.attrb1, self.attrb2

Тогда решение действительно простое:

bar.sort (ключ = foo.sort, reverse = True)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...