How to sort a List in Python on variable number of parameters

Question:

I have a list of dictionaries, that I have to sort. However, the key/parameter on which to sort will be determined dynamically. The way this is done is I will create a method which will take the list and sorting columns as input as follows:

def processList(l, sortId= None):
    <logic>
    return l

Here’s an example:
I have 5 dictionaries in a list:

[
    {'name': 'alpha', 'price': 200, 'date': '2022-02-01'},
    {'name': 'beta', 'price': 400, 'date': '2022-03-01'},
    {'name': 'delta', 'price': 500, 'date': '2022-05-01'},
    {'name': 'zeta', 'price': 400, 'date': '2022-02-10'},
    {'name': 'kappa', 'price': 500, 'date': '2022-01-31'}
]

Now, I wish to sort it, but sorting criteria can be determined at runtime. So I can have sorting done by name and the output will be:

>>> l.sort(key=lambda x:x['name'])
[
    {'name': 'alpha', 'price': 200, 'date': '2022-02-01'},
    {'name': 'beta', 'price': 400, 'date': '2022-03-01'},
    {'name': 'delta', 'price': 500, 'date': '2022-05-01'},
    {'name': 'kappa', 'price': 500, 'date': '2022-01-31'},
    {'name': 'zeta', 'price': 400, 'date': '2022-02-10'}
]

or sort by price and date:

>>> l.sort(key=lambda x:(x['price'], x['date']))

[
    {'name': 'alpha', 'price': 200, 'date': '2022-02-01'},
    {'name': 'zeta', 'price': 400, 'date': '2022-02-10'},
    {'name': 'beta', 'price': 400, 'date': '2022-03-01'},
    {'name': 'kappa', 'price': 500, 'date': '2022-01-31'},
    {'name': 'delta', 'price': 500, 'date': '2022-05-01'}
]

I can’t loop in over all the sorting columns because in the next iteration, it will rearrange/sort the data with respect to that column.

Is there a way to unpack the keys within lambda?

Answers:

You can easily use custom list comprehension to write it like this:

l = sorted(l, key=lambda x: [ x[col] for col in sortId])
Answered By: Amirrad
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.