Reputation: 1461
I have some code that generates a nested dictionary structure. I'm then printing it as YAML by doing the following:
print(yaml.dump(mydict, sort_keys=False))
the data structure looks something like the following
"DeviceInfo": {
"autoApply": 'true',
"comment": "this is a test",
"contact": {
"email": "Hello",
"name": "aaaaa",
"phoneNumber": "(111) 111 111"
},
"location": {
"address": "2100 Moorpark Ave",
"city": "San Jose",
"country": "US",
"latitude": 36,
"longitude": 119,
"state": "California",
"zipCode": 94088
},
"networkRole": "non-hub",
"region": "North",
"group": "Group 1",
}}
and the resulting YAML:
DeviceInfo:
autoApply: 'true'
comment: this is a test
contact:
email: Hello
name: aaaaa
phoneNumber: (111) 111 111
location:
address: 2100 Moorpark Ave
city: San Jose
country: US
latitude: 36
longitude: 119
state: California
zipCode: 94088
networkRole: non-hub
region: North
group: Group 1
what I would like to do is order the dictionary and therefore resulting YAML by key depth.
So have the output look like this.
DeviceInfo:
autoApply: 'true'
comment: this is a test
networkRole: non-hub
region: North
group: Group 1
contact:
email: Hello
name: aaaaa
phoneNumber: (111) 111 111
location:
address: 2100 Moorpark Ave
city: San Jose
country: US
latitude: 36
longitude: 119
state: California
zipCode: 94088
From testing yaml.dump ( with sort_keys=False ) seems to preserve the order of the dictionary. So what I am trying to accomplish is to sort the dictionary by ascending depth.
Upvotes: 1
Views: 291
Reputation: 107015
You can use a recursive worker function that returns a tuple consisting of the depth of the current given dict and the dict sorted by depths of the keys. The base case of the recursion would be a depth of 0 when the given object is not a dict. The depth of the current dict is calculated as the maximum depth of all children plus 1:
def sort_dict_by_depth(d):
def _sort_dict_by_depth(d):
if isinstance(d, dict):
children_depths = [(k, _sort_dict_by_depth(v)) for k, v in d.items()]
return (
max(depth for _, (depth, _) in children_depths) + 1,
{k: v for k, (_, v) in sorted(children_depths, key=lambda t: t[1][0])}
)
return 0, d
return _sort_dict_by_depth(d)[1]
Demo: https://replit.com/@blhsing/GrandBurlyDividend
Upvotes: 2