65

I'm trying to sort OrderedDict in OrderedDict by 'depth' key. Is there any solution to sort that Dictionary ?

OrderedDict([
  (2, OrderedDict([
    ('depth', 0),  
    ('height', 51), 
    ('width', 51),   
    ('id', 100)
  ])), 
  (1, OrderedDict([
    ('depth', 2),  
    ('height', 51), 
    ('width', 51),  
    ('id', 55)
  ])), 
  (0, OrderedDict([
    ('depth', 1),  
    ('height', 51), 
    ('width', 51),  
    ('id', 48)
  ])),
]) 

Sorted dict should look like this:

OrderedDict([
  (2, OrderedDict([
    ('depth', 0),  
    ('height', 51), 
    ('width', 51),   
    ('id', 100)
  ])), 
  (0, OrderedDict([
    ('depth', 1),  
    ('height', 51), 
    ('width', 51),  
    ('id', 48)
  ])),
  (1, OrderedDict([
    ('depth', 2),  
    ('height', 51), 
    ('width', 51),  
    ('id', 55)
  ])), 
]) 

Any idea how to get it?

martineau
  • 119,623
  • 25
  • 170
  • 301
Damian Gądziak
  • 895
  • 1
  • 9
  • 12

3 Answers3

117

You'll have to create a new one since OrderedDict is sorted by insertion order.

In your case the code would look like this:

foo = OrderedDict(sorted(foo.items(), key=lambda x: x[1]['depth']))

See http://docs.python.org/dev/library/collections.html#ordereddict-examples-and-recipes for more examples.

Note for Python 2 you will need to use .iteritems() instead of .items().

Gulzar
  • 23,452
  • 27
  • 113
  • 201
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • 3
    This will cause an exception if any dict doesn't have 'depth' as a key. This might be desired. If it isn't, you can assume a default key by using "get". – TomOnTime Sep 04 '13 at 10:17
  • 11
    Note that `[1]` here refers to foo's values, as opposed to its keys, which would be `[0]` – e18r Mar 29 '16 at 17:14
20
>>> OrderedDict(sorted(od.items(), key=lambda item: item[1]['depth']))
Raymond Hettinger
  • 216,523
  • 63
  • 388
  • 485
5

Sometimes you might want to keep the initial dictionary and not create a new one.

In that case you could do the following:

temp = sorted(list(foo.items()), key=lambda x: x[1]['depth'])
foo.clear()
foo.update(temp)
johnson
  • 3,729
  • 3
  • 31
  • 32
  • I am curious, can you give an example when one would want to clear and update an existing dictionary, instead of re-assigning it? – Ataxias Dec 31 '21 at 02:37
  • 1
    When you are handling dicts that might have been subclassed – johnson Jan 01 '22 at 09:11
  • @johnson Good point. A real world example for those not convinced: I recently ran across a situation using ruamel.yaml, where if I wanted to rearrange a `CommentedMap` type using custom sorting, this is could be appropriate, or else it wouldn't be able to serialize. Not sure if the `CommentedMap` constructor would have been able to be used for this. – NanoTree Jun 13 '23 at 17:11