Reputation: 3189
I have some sort of trie composed of OrderedDicts (but in the wrong order) which looks like this:
test = {
'ab':{
'1':{},
'2':{
'002':{},
'001':{}}},
'aa':{
'02':{
'ac':{},
'01':{},
'ca':{},
'ab':{}},
'01':{
'b':{},
'z':{
'0':{},
'1':{}}}}
}
How can I get a complete ordering of this dict in all subsequent levels?
If I use collections.OrderedDict(sorted(test.iteritems())) I get it sorted only for the first level.
I feel that I need to create a function that it will somehow call itself recursively until the deepest level, but after I spent many hours trying different ways to solve the problem, I am still stuck here.
Eventually it has to look like this:
test = {
'aa':{
'01':{
'b':{},
'z':{
'0':{},
'1':{}}},
'02':{
'01':{},
'ab':{},
'ac':{},
'ca':{}}},
'ab':{
'1':{},
'2':{
'001':{},
'002':{}}}
}
Upvotes: 4
Views: 197
Reputation: 653
from collections import OrderedDict as OD
def order(X):
retval = OD()
# The standard iterator of a dict is its keys.
for k in sorted(X):
# Incase it something we can't handle.
if isinstance(X[k], dict):
# I want my children dicts in order.
retval[k] = order(X[k])
else:
retval[k] = X[k]
return retval
Upvotes: 1
Reputation: 23251
With recursion, remember there are two cases: the branch, and the leaf. Be sure to account for both.
def make_ordered(d):
if isinstance(d, dict):
return OrderedDict(sorted((key, make_ordered(value)) for key, value in d.iteritems()))
else:
return d
Upvotes: 3
Reputation: 16226
If you can afford an extra dependency I would recommend blist package. It provides many sorted containers including sorteddict
. Then your dictionary would just always stay sorted.
Check the sorteddict class docs for exact usage. The package itself is production quality and BSD licence, so not a problem to use in any proprietary code.
Upvotes: 1