1

I would like to return a dictionary where values are lists sorted by descending length of values.

ex.

data = {'r': [4,3],'t': [4,5,6], 'n': [1,6]}

must give

data = {'t': [4,5,6], 'r': [4,3],'n': [1,6]}

Then, after this first sort, I would like that keys be sorted in alphabetical order for values of same length, as with

data = {'t': [4,5,6], 'n': [1,6], 'r': [4,3]} 

Is there a way?

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • 3
    This question has been asked several times, see for example [here](http://stackoverflow.com/search?q=[python]dict+sort). – Bakuriu May 27 '13 at 18:04
  • 1
    But if you decided that it's okay to return a list like `[('t', [4,5,6]), ('n',[1,6]), ('r',[4,3])]` then people here can help. – Apiwat Chantawibul May 27 '13 at 18:06

1 Answers1

7

You can't sort a regular Python dictionary. They have no order. You can, however, use collections.OrderedDict:

from collections import OrderedDict

data = {'r': [4,3],'t': [4,5,6], 'n': [1,6]}
tuples = data.items()
tuples.sort(key=lambda pair: len(pair[1]), reverse=True)

ordered = OrderedDict(tuples)

And the result:

OrderedDict([('t', [4, 5, 6]), ('r', [4, 3]), ('n', [1, 6])])

lambda pair: len(pair[1]) is your key function, so given a (key, value) pair, it returns the length of the values. You can also use (len(pair[1]), key) to sort alphabetically if two pairs have the same value length.

Blender
  • 289,723
  • 53
  • 439
  • 496
  • I think the OP would want `pair[0]` or `pair[0].lower()` to be the second element. (I used `(-len(pair[1]), pair[0].lower())` as the tuple, and no reverse.) – DSM May 27 '13 at 18:05
  • @DSM: I wasn't sure if the key name or the value was going to break ties. I'll just leave that part off then – Blender May 27 '13 at 18:06
  • 1
    The way I read the "alphabetical order" sentence it's by length of value and then alphabetical on key, but I could be misreading it (and it's likely enough anyway that there are other yet-unspecified criteria..) – DSM May 27 '13 at 18:09