Valkry Valkry - 14 days ago 6
Python Question

How do I sort a dictionary containing lists of dictionaries in python?

my data looks like this:

data = {'field1': [{'id': <some-string>,
'x': <number-to-sort-on>}, ...],
'field2': [{'id': <some-string>,
'x': <some-number>}, ...]
... }


Basically I want to take as input the field name ('field1', 'field2', etc). My code should then sort the list of dictionaries (desc order) for that field based on the 'x' value. However, I also am trying to have all other 'fields' update according to the original sort. Let me give an example.

data = {'field1': [{'id': 'firstID', 'x': 3}, {'id': 'secondID', 'x': 6}],
'field2': [{'id': 'firstID', 'x': 4}, {'id': 'secondID', 'x': 1}]}


Upon receiving an input of 'field1', a sort operation should transform my data to the following:

data = {'field1': [{'id': 'secondID', 'x': 6}, {'id': 'firstID', 'x': 3}],
'field2': [{'id': 'secondID', 'x': 1}, {'id': 'firstID', 'x': 4}]}

Answer
field_value = data['field1']                 # extract the value for the input field name

for k,v in data.items():
    # sort the values for each key based on the values of the extracted fields
    sorted_value = sorted(enumerate(v), key=lambda (i, _): field_value[i]['x'], reverse=True)
    data[k] = [v[1] for v in sorted_value]

data
# {'field1': [{'id': 'secondID', 'x': 6}, {'id': 'firstID', 'x': 3}],
#  'field2': [{'id': 'secondID', 'x': 1}, {'id': 'firstID', 'x': 4}]}

Another option similar to the argsort() method of numpy, you can obtain a list of index which sorts the value corresponding to field1 and then use the list of index to sort all other values:

field_value = data['field1']
argsort_lst = [i for i, _ in sorted(enumerate(field_value), key=lambda (i,v): v['x'], reverse=True)]

argsort_lst
# [1, 0]

for v in data.values():
    v[:] = [v[i] for i in argsort_lst]

data
# {'field1': [{'id': 'secondID', 'x': 6}, {'id': 'firstID', 'x': 3}],
#  'field2': [{'id': 'secondID', 'x': 1}, {'id': 'firstID', 'x': 4}]}