1

I am looking for a way to sort a dictionary by values. But here is the catch, my values are dictionaries as well. So I want to sort by my value dictionary's first value.

For example given the dictionary:

x = {'a':{'b':1, 'c':2, 'd':3}, 'e':{'f':3, 'g':4, 'h':5}, 'i':{'j':2, 'k':3, 'l':4}}

I would like the dictionary to be sorted by the values 'b', 'f', and 'j'. The sorted dictionary would return as:

x = {'a':{'b':1, 'c':2, 'd':3}, 'i':{'j':2, 'k':3, 'l':4}, 'e':{'f':3, 'g':4, 'h':5}}

Any help would be amazing. Preferably, I am looking for a solution that uses the sorted method along with lambdas.

agua95
  • 67
  • 3
  • When you say "first", do you mean "any arbitrary value"? Because the inner dictionaries are *also* not ordered by anything in particular, so you might not get `'b'` `'f'` and `'j'` as the three first keys if you built those inner dictionaries differently. If you want "the value corresponding to the first key in alphabetical order", that's a different thing. – Blckknght Feb 05 '20 at 20:24

3 Answers3

1

Default dict type don't ordered.
Use collections.OrderedDict.
Sort OrderedDict question

Georgiy
  • 3,158
  • 1
  • 6
  • 18
  • This helped a lot. Here was my final solution `sorted(monthcounts.items(), key=lambda x: x[1]['fieldname'], reverse=True)`. However, this assumes that all fields being compared share the same name. – agua95 Feb 06 '20 at 19:15
0

Dictionaries in Python are not explicitly ordered. ATM in an iterable they are guaranteed to return keys in the order they were inserted. Try using an OrderedDict dictionary from the collections package if you will be using dictionaries like this frequently. If you're only interested in sorting the dictionary based on its values first value, the following will work.

def get_sort_key(x):
    def get_key(elt):
        for k, v in x[elt].items():
            return v
    return get_key

sorted(x, key=get_sort_key(x))

This returns a list of the main dict's keys in order. The iterator of a dictionary is a list of the keys, so it's probably better to use sorted on x.items() and then construct a new dictionary from that.

bbbbbb
  • 116
  • 6
0

Use the sorted function and supply it a combination of next and iter as the key:

x = dict(sorted(x.items(), key=lambda y: next(iter(y))))

This works by turning the dict into an iterator and next gets the first key from that iterator, as sorted returns a list thus being a list of key, value tuples use dict on the sorted result to get a dict as a result.

{'a': {'b': 1, 'c': 2, 'd': 3}, 'e': {'f': 3, 'g': 4, 'h': 5}, 'i': {'j': 2, 'k': 3, 'l': 4}}
Jab
  • 26,853
  • 21
  • 75
  • 114
  • This isn't quite right, as it sorts by key, not by the corresponding value. The expected result according to the question is that the `2` from the `'j'` key ends up sorting its dictionary ahead of the `3` from the `'f'` key. – Blckknght Feb 05 '20 at 20:53