One liner function for sorting a string list of lists in ascending, descending order based on varying criteria in python

Question

Let's assume that I have the following list of lists:

[[list1], [list2], ..., [listK]]

where list1, list2, ..., listK are lists of N strings.

 [list1] = [string11, string12, ..., string1N]
 [list2] = [string21, string22, ..., string2N]
    .              .
    .              .
    .              .

Now, let's say I want to choose some specific subset of inner list to be sorted in a descending order, and the rest in ascending order. For instance, let's assume that N=5, and I first would like to sort the outer list by sorting by first, third, fifth strings of the inner list in the ascending order and by then second and fourth strings in the descending order.

If I didn't care about the ascending/descending, and wanted to sort all in the ascending order, there would be an easy one liner solution to it:

outer_list.sort(key = lambda lst: (lst[0], lst[2], lst[4], lst[1], lst[3]))

but since we have a condition: first, third, fifth strings of the inner list in the ascending order and then by second and fourth strings in the descending order, I was wondering if there's a simple addition to the code above to make it a one liner solution.


Show source
| sorting   | list   | python   | string   2017-01-03 03:01 2 Answers

Answers to One liner function for sorting a string list of lists in ascending, descending order based on varying criteria in python ( 2 )

  1. 2017-01-03 04:01

    Sorting is stable in python but .sort is in-place. So if you insist on a single line you could do something like this with sorted:

    outer_list = sorted(sorted(outer_list, key=lambda x: (x[0], x[2], x[4])), key=lambda x: (x[1], x[3]), reverse=True)
    
  2. 2017-01-03 04:01

    In addition to all of the other fine answers here, you can also write your own ordering class:

    from functools import total_ordering
    
    @total_ordering
    class MyOrdering(object):
        def __init__(self, value):
            self.value = value
        def __eq__(self, other):
            return other.value == self.value
        def __lt__(self, other):
            for i in [0, 2, 4]:
                if self.value[i] != other.value[i]:
                    return self.value[i] < other.value[i]
            for i in [1, 3]:
                if self.value[i] != other.value[i]:
                    return self.value[i] > other.value[i]
            return False
    

    And then you can sort using the MyOrdering class as your key function:

    outer_list.sort(key=MyOrdering)
    

Leave a reply to - One liner function for sorting a string list of lists in ascending, descending order based on varying criteria in python

◀ Go back