How to deal with what you've got
Your existing data structure is a bit crazy, but here is how I would handle it (edit suppose the key for the color list was 123
):
>>> to_sort = [
... ('Fruits',
... {
... 'size': {1:[4, 2, 7,9]},
... 'name': {1:['Orange', 'Apple', 'Kiwi', 'Mango']},
... 'color': {123:['Orange', 'Red', 'Brown','Green']},
... 'order': {1:[2, 1, 4,3]}
... }
... )
... ]
>>> d = to_sort[0][1]
>>> keys = list(d.keys())
>>> idx = keys.index('order')
>>> ordered_kv = zip(keys, zip(*sorted(zip(*(d[k][n] for k in keys for n in d[k])), key = lambda t:t[idx])))
>>> sorted_dict = {k:{n:list(v) for n in d[k]} for k,v in ordered_kv}
>>> from pprint import pprint
>>> pprint(sorted_dict)
{'color': {123: ['Red', 'Orange', 'Green', 'Brown']},
'name': {1: ['Apple', 'Orange', 'Mango', 'Kiwi']},
'order': {1: [1, 2, 3, 4]},
'size': {1: [2, 4, 9, 7]}}
Let's break this down: First, I made a canonical list of keys and find the index of 'order'
:
>>> keys = list(to_sort[0][1].keys())
>>> idx = keys.index('order')
The next step is to zip
the internal lists together into tuples where each of the items share the same relative position:
>>> list(zip(*(d[k][n] for k in keys for n in d[k])))
[(4, 2, 'Orange', 'Orange'), (2, 1, 'Red', 'Apple'), (7, 4, 'Brown', 'Kiwi'), (9, 3, 'Green', 'Mango')]
This can be sorted now according the the idx
position and then "unzipped" (which really just means applying the zip-splat combination again:
>>> list(zip(*sorted(zip(*(d[k][n] for k in keys for n in d[k])), key=lambda t:t[idx])))
[(2, 4, 9, 7), (1, 2, 3, 4), ('Red', 'Orange', 'Green', 'Brown'), ('Apple', 'Orange', 'Mango', 'Kiwi')]
And finally, you rebuild your crazy dictionary with a dictionary comprehension, making sure to zip up your ordered values with the original keys:
>>> ordered_kv = zip(keys, zip(*sorted(zip(*(d[k][n] for k in keys for n in d[k])), key = lambda t:t[idx])))
>>> sorted_dict = {k:{n:list(v) for n in d[k]} for k,v in ordered_kv}
>>> from pprint import pprint
>>> pprint(sorted_dict)
{'color': {123: ['Red', 'Orange', 'Green', 'Brown']},
'name': {1: ['Apple', 'Orange', 'Mango', 'Kiwi']},
'order': {1: [1, 2, 3, 4]},
'size': {1: [2, 4, 9, 7]}}
However...
You should really consider using the pandas
library for manipulating data like this. Observe:
>>> import pandas as pd
>>> df = pd.DataFrame({k: pd.Series(v[1]) for k,v in to_sort[0][1].items()})
>>> df
color name order size
0 Orange Orange 2 4
1 Red Apple 1 2
2 Brown Kiwi 4 7
3 Green Mango 3 9
Notice I still had to finagle your original data structure into a pandas
DataFrame, but if you start whatever you are doing with a DataFrame
to begin with, it will all be much easier. Now you can do cool things like:
>>> df.sort_values('order')
color name order size
1 Red Apple 1 2
0 Orange Orange 2 4
3 Green Mango 3 9
2 Brown Kiwi 4 7