1

I am trying to sort a list by multiple conditions using this code.

lis = sorted([lsDataSorted[i:i+8] for i in range(0,len(lsDataSorted),8)],key=lambda x:(x[7],int(x[5])-int(x[6]),x[5],x[0]),reverse=True)

Now, we don't need to bother talking about what each object is, but we see that I have an "reverse" sorting function. Now, my last condition x[0] happens to be a list of names. By using the reverse=True, we know that the sorting will be in reverse order (z-a). My question is, can I "reverse" back to normal only for the last condition? If yes, then how?

zch
  • 14,931
  • 2
  • 41
  • 49
Diaco
  • 241
  • 1
  • 3
  • 15
  • [This answer](http://stackoverflow.com/a/6667177/1126943) should help you. – zch Jan 06 '15 at 01:53
  • See [this question](http://stackoverflow.com/questions/1516249/python-list-sorting-with-multiple-attributes-and-mixed-order) and its answers. – ErikR Jan 06 '15 at 01:53
  • okay so in other Words, its just better to write a new line with the same lambda thing, but with the last condition? – Diaco Jan 06 '15 at 01:59
  • What is `lsDataSorted`? ANy example of what it is? – Marcin Jan 06 '15 at 02:14
  • its a list ls = ["name1","a1","b1","c1",..."h1","name2","a2","b2","c2"...] and so on. 8 different "categories" that I want to sort by some of the conditions. Its actually going to be a table in the end where I am sorting according to some values and lastly the names of the objects – Diaco Jan 06 '15 at 02:23
  • Actually it is a bad name since its not "sorted" in our context since we are going to sort it... but what I meant was that the objects are sorted in terms of being on the right positions – Diaco Jan 06 '15 at 02:24

1 Answers1

4

I would recommend wrapping each chunk of lsDataSorted into a custom class that will enforce comparison by your complex condition. For example:

import functools

@functools.total_ordering
class Compare(object):
    def __init__(self, chunk):
        self.x = chunk[7], int(chunk[5]) - int(chunk[6]), chunk[5]
        self.y = chunk[0]
    def __eq__(self, other):
        return (self.x==other.x) and (self.y==other.y)
    def __lt__(self, other):
        if self.x != other.x:
            return self.x < other.x
        return self.y > other.y

Now,

lis = sorted([lsDataSorted[i:i+8]
              for i in range(0,len(lsDataSorted),8)],
              key=Compare, reverse=True)

should give you the mixed complex sorting you're apparently looking for.

jamylak
  • 128,818
  • 30
  • 231
  • 230
Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395