Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python sort list of lists over multiple levels and with a custom order

I have a list of lists my_list e.g.

[
['item 3.1', 'item 3.2', 'item 3.3', 'item 3.4', 'item 3.5'],
['item 3.1', 'item 3.2', 'item 3.2', 'item 3.2', 'item 3.2'],
['item 3.1', 'item 3.2', 'item 3.2', 'item 3.6', 'item 3.2'],
['item 3.1', 'item 2.2', 'item 2.4', 'item 2.7', 'item 2.5'],
['item 2.1', 'item 2.2', 'item 2.3', 'item 2.4', 'item 2.5'],
['item 1.1', 'item 1.2', 'item 1.3', 'item 1.4', 'item 1.5'],
['item 4.1', 'item 4.2', 'item 4.3', 'item 4.4', 'item 4.5'],
['item 1.1', 'item 1.2', 'item 1.3', 'item 1.5', 'item 1.5']
]

I want to order this list on multiple levels with 1 of the levels being a customer order but don't know how to do this.

e.g. I want to order by the first item first then within that order, order them by the third item then within that order, order by the fourth item. But I want the first item to be ordered/sorted in this particular order rather than alphabetical:

item 4.1
item 2.1
item 3.1
item 1.1

so the final list (after sorting) would be:

[
['item 4.1', 'item 4.2', 'item 4.3', 'item 4.4', 'item 4.5']
['item 2.1', 'item 2.2', 'item 2.3', 'item 2.4', 'item 2.5'],
['item 3.1', 'item 3.2', 'item 3.2', 'item 3.2', 'item 3.2'],
['item 3.1', 'item 3.2', 'item 3.2', 'item 3.6', 'item 3.2'],
['item 3.1', 'item 3.2', 'item 3.3', 'item 3.4', 'item 3.5'],
['item 3.1', 'item 2.2', 'item 2.4', 'item 2.7', 'item 2.5'],
['item 1.1', 'item 1.2', 'item 1.3', 'item 1.4', 'item 1.5'],
['item 1.1', 'item 1.2', 'item 1.3', 'item 1.5', 'item 1.5'],
]

I know I can sort over multiple levels by doing:

s = sorted(my_list, key=itemgetter(0,2,3))

But this would sort them all alphabetically and what I don't know how to do is set the first column to be sorted by the custom order.

like image 325
John Avatar asked Feb 28 '13 14:02

John


People also ask

How do you sort a list with a custom function in Python?

Custom Sorting With key= For more complex custom sorting, sorted() takes an optional "key=" specifying a "key" function that transforms each element before comparison. The key function takes in 1 value and returns 1 value, and the returned "proxy" value is used for the comparisons within the sort.

How do I sort a Python list by specific order?

sort() is one of Python's list methods for sorting and changing a list. It sorts list elements in either ascending or descending order. sort() accepts two optional parameters. reverse is the first optional parameter.

How do you sort a mixed list in Python?

Method #2 : Using sorted() + key + lambda + isdigit() The combination of above functionalities can also be used to achieve solution to this problem. In this, we just sort the list using sorted() using key functionality using lambda function to segregate digits using isdigit().

How do you sort a list with multiple criteria in Python?

sort() function. A Pythonic solution to in-place sort a list of objects using multiple attributes is to use the list. sort() function. It accepts two optional keyword-only arguments: key and reverse and produces a stable sort.


1 Answers

Ugly and inefficient, but probably working:

order = ['item 4.1', 'item 2.1', 'item 3.1', 'item 1.1']
my_list.sort(key=lambda x: order.index(x[0]))

reorders my_list to:

[['item 4.1', 'item 4.2', 'item 4.3', 'item 4.4', 'item 4.5'],
 ['item 2.1', 'item 2.2', 'item 2.3', 'item 2.4', 'item 2.5'],
 ['item 3.1', 'item 3.2', 'item 3.3', 'item 3.4', 'item 3.5'],
 ['item 3.1', 'item 3.2', 'item 3.2', 'item 3.2', 'item 3.2'],
 ['item 3.1', 'item 3.2', 'item 3.2', 'item 3.6', 'item 3.2'],
 ['item 3.1', 'item 2.2', 'item 2.4', 'item 2.7', 'item 2.5'],
 ['item 1.1', 'item 1.2', 'item 1.3', 'item 1.4', 'item 1.5'],
 ['item 1.1', 'item 1.2', 'item 1.3', 'item 1.5', 'item 1.5']]

If you want to sort by first column in a customized way, then by the third and fourth alphabetically, just expand the key:

my_list.sort(key=lambda x: (order.index(x[0]), x[2], x[3]))

which returns

[['item 4.1', 'item 4.2', 'item 4.3', 'item 4.4', 'item 4.5'],
 ['item 2.1', 'item 2.2', 'item 2.3', 'item 2.4', 'item 2.5'],
 ['item 3.1', 'item 2.2', 'item 2.4', 'item 2.7', 'item 2.5'],
 ['item 3.1', 'item 3.2', 'item 3.2', 'item 3.2', 'item 3.2'],
 ['item 3.1', 'item 3.2', 'item 3.2', 'item 3.6', 'item 3.2'],
 ['item 3.1', 'item 3.2', 'item 3.3', 'item 3.4', 'item 3.5'],
 ['item 1.1', 'item 1.2', 'item 1.3', 'item 1.4', 'item 1.5'],
 ['item 1.1', 'item 1.2', 'item 1.3', 'item 1.5', 'item 1.5']]
like image 196
eumiro Avatar answered Nov 08 '22 12:11

eumiro