0

I want to reverse sort a dictionary of lists based on the number of items in each list, and keep the keys for further processing. I.e. I do not want a list returned.

Example:

test = {346: [235, 238], 347: [129, 277], 348: [115, 191, 226], 349: [194, 328], 351: [150, 70, 118], 352: [123, 334], 353: [161, 196]}

After sorting the dict the desired output should be something like:

test = {348: [115, 191, 226], 351: [150, 70, 118], 346: [235, 238], 347: [129, 277], 349: [194, 328], 352: [123, 334], 353: [161, 196]}

What I have come up with so far is:

def get_length(element):
    return len(element)


test = {346: [235, 238], 347: [129, 277], 348: [115, 191, 226], 349: [194, 328], 351: [150, 70, 118], 352: [123, 334], 353: [161, 196]}

s = sorted(test.values(), key=get_length, reverse=True)

It correctly sorted as desired, but this breaks my dictionary and results in:

s = [[115, 191, 226], [150, 70, 118], [235, 238], [129, 277], [194, 328], [123, 334], [161, 196]]

As you can see the keys are gone, and the data is useless for further processing.

What am I missing? Big thanks to anyone who can help me sort this out.

jpp
  • 159,742
  • 34
  • 281
  • 339
greatwhitehat
  • 39
  • 1
  • 5
  • 1
    Possible duplicate of [How do I sort a dictionary by value?](https://stackoverflow.com/questions/613183/how-do-i-sort-a-dictionary-by-value) – jasonharper Feb 02 '18 at 13:04
  • Dictionaries are not deemed to be sorted, although they may be in the future. Therefore, your desired output should be a list of tuples. – jpp Feb 02 '18 at 13:20
  • OK, thanks. I guess it is time for a less elegant solution. Will try and get this question closed. – greatwhitehat Feb 02 '18 at 13:26
  • @greatwhitehat, I've provided a solution below using `collections.OrderedDict`. – jpp Feb 02 '18 at 13:52

1 Answers1

0

It looks like you have 2 levels of processing: first by key, then by length of value.

As per my comment above, the output is a list of tuples, as currently ordered dictionaries are considered an implementation detail.

If you wish to use an ordered dictionary, use collections.OrderedDict as below.

from collections import OrderedDict

test = {346: [235, 238], 347: [129, 277], 348: [115, 191, 226], 349: [194, 328], 351: [150, 70, 118], 352: [123, 334], 353: [161, 196]}

s1 = OrderedDict(sorted(test.items()))
s2 = sorted(s1.items(), key=lambda k: len(s1[k[0]]), reverse=True)

# [(348, [115, 191, 226]),
#  (351, [150, 70, 118]),
#  (346, [235, 238]),
#  (347, [129, 277]),
#  (349, [194, 328]),
#  (352, [123, 334]),
#  (353, [161, 196])]

d = OrderedDict(s2)

# OrderedDict([(348, [115, 191, 226]),
#              (351, [150, 70, 118]),
#              (346, [235, 238]),
#              (347, [129, 277]),
#              (349, [194, 328]),
#              (352, [123, 334]),
#              (353, [161, 196])])
jpp
  • 159,742
  • 34
  • 281
  • 339