Ryohei De Iwata
Ryohei De Iwata

Reputation: 91

Sorting list of nested dictionaries in python 3

I am trying to sort a dictionary containing dictionaries. Here is that dictionary:

mydict = {
  'b': {'play': 2, 'scratch': 5, 'face': 8},
  'c': {'do': 4, 'chew': 6},
  'a': {'wash': 1, 'drink': 10, 'give': 20, 'eat': 30}
}

I want the following result after sorting:

{
  'a': {'eat': 30, 'give': 20, 'drink': 10, 'wash': 1},
  'b': {'face': 8, 'scratch': 5, 'play': 2},
  'c': {'chew': 6, 'do': 4}
}

I will appreciate if you tell me how to solve this issue.

Upvotes: 2

Views: 921

Answers (1)

John1024
John1024

Reputation: 113844

Creating an ordered version of mydict

Let's start with your dictionary:

>>> mydict = {
...   'b': {'play': 2, 'scratch': 5, 'face': 8},
...   'c': {'do': 4, 'chew': 6},
...   'a': {'wash': 1, 'drink': 10, 'give': 20, 'eat': 30}
... }

Ordinary dictionaries are unordered. Ordered dictionaries, however are available from the collections module:

>>> from collections import OrderedDict

We can convert your dictionary to an ordered dictionary as follows:

>>> d = OrderedDict(sorted(mydict.items()))
>>> d
OrderedDict([('a', {'give': 20, 'drink': 10, 'eat': 30, 'wash': 1}), ('b', {'scratch': 5, 'play': 2, 'face': 8}), ('c', {'do': 4, 'chew': 6})])

As you can see above, d is ordered as we want. Alternatively, we can look at just the keys and verify they are in the order that we want:

>>> d.keys()
odict_keys(['a', 'b', 'c'])

In other ways, our ordered dictionary d behaves just like a regular dictionary:

>>> d['a']
{'give': 20, 'drink': 10, 'eat': 30, 'wash': 1}

Ordering mydict by key while ordering the dictionaries inside it by value in descending order

If we want the dictionaries inside mydict to be sorted in descending order of value, we use an OrderedDict again:

>>> mydict['a']
{'give': 20, 'drink': 10, 'eat': 30, 'wash': 1}
>>> OrderedDict(sorted(mydict['a'].items(), key=lambda v: -v[-1]))
OrderedDict([('eat', 30), ('give', 20), ('drink', 10), ('wash', 1)])

If we want to apply this ordering to all entries of mydict:

>>> d = OrderedDict( sorted( (key1, OrderedDict(sorted(value.items(), key=lambda v: -v[-1]))) for (key1, value) in mydict.items()) )
>>> d
OrderedDict([('a', OrderedDict([('eat', 30), ('give', 20), ('drink', 10), ('wash', 1)])), ('b', OrderedDict([('face', 8), ('scratch', 5), ('play', 2)])), ('c', OrderedDict([('chew', 6), ('do', 4)]))])

Upvotes: 3

Related Questions