I have a list whose elements are dictionaries with a value and a type field, i.e.:
my_list = [{'val':5, 'type':0},{'val':6, 'type':2},{'val':2, 'type':1},{'val':9, 'type':0}]
I would like to sort this list in descending order based on the type
field and within each type based on the value
field, and obtain a vector with the corresponding indexes of the sorting along with the sorted vector.
I know how to do it for an individual criteria using a lambda
function, i.e.:
sorted_list = sorted(my_list, key=lambda k: k['type'], reverse=True)
but how do I extend it to multiple criteria?
Desired output:
sorted_list = [{'val':6, 'type':2},{'val':2, 'type':1},{'val':9, 'type':0},{'val':5, 'type':0}]
sorted_idxs = [1, 2, 3, 0]`, such that `[my_list[k] for k in sorted_idxs]==sorted_list
If the key
returns a tuple, sorted
will consider them in order when sorting:
In [3]: sorted(my_list, key=lambda k: (k['type'], k['val']), reverse=True)
Out[3]:
[{'type': 2, 'val': 6},
{'type': 1, 'val': 2},
{'type': 0, 'val': 9},
{'type': 0, 'val': 5}]
If you want the indices, just throw an enumerate
in there as well:
In [7]: sorted(enumerate(my_list), key=lambda k: (k[1]['type'], k[1]['val']), reverse=True)
Out[7]:
[(1, {'type': 2, 'val': 6}),
(2, {'type': 1, 'val': 2}),
(3, {'type': 0, 'val': 9}),
(0, {'type': 0, 'val': 5})]
In [8]: [k for k, v in sorted(enumerate(my_list), key=lambda k: (k[1]['type'], k[1]['val']), reverse=True)]
Out[8]: [1, 2, 3, 0]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With