开发者

How to perform double sort inside an array?

I don't know the exact term exists for this type of sorting. Here is the problem - I have a class foo

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

    def sort(self):
        return self.attrb1 

An array "bar" contain objects of type foo. I want to sort the array in descending order according to the two attributes. First by attrb1

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

Then I want to sort the sorted elements within themselves according to attrb2. So for two elements foo1 and foo2 in the array we have -

foo1 > foo2 
if foo1.attrb1 > foo2.attrb1
elif foo1.attrb1 ==开发者_高级运维 foo2.attrb1
foo1.attrb2 > foo2.attrb2

How can I do this?


bar.sort(key=lambda x: (x.attrb1, x.attrb2), reverse=True)

And you don't need to define foo.sort


You're using classes already so just implement __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)


Sort already do this if you have a tuple of values. If you change the method sort to return a tuple:

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

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

Then the solution is really simple:

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


You can also do it without lambda (which I personally don't like):

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

operator.attrgetter works like this:

a = foo(3,4)
b = operator.attrgetter("attrb1","attrb2")(a)
print(b) #  You get (3,4)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜