Reputation: 105
Extract all the keys from an Ordered dict recursively
I have tried using some recursive functions available online but could get what I was looking for.
The input ordered dictionary takes the below value
input = OrderedDict([('report',
OrderedDict([('generated_at', '2019-07-01 05:07:13'),
('record_count', 23),
('start_date', '2019-02-10'),
('end_date', '2019-02-10'),
('records',
[OrderedDict([('_data_type', 'PREGNANT'),
('_app_type', 'DAYS_POST')]),
OrderedDict([('_data_type', 'VISION'),
('_app_type', 'DAYS_PRE')])])]))])
The expected output is a list of all the keys including nesting.
['generated_at','record_count','start_date','end_date','_data_type','_app_type']
The order needs to be in the above specified sequence.
Upvotes: 1
Views: 381
Reputation: 61910
You could do the following:
from collections import OrderedDict
ipt = OrderedDict([('report',
OrderedDict([('generated_at', '2019-07-01 05:07:13'),
('record_count', 23),
('start_date', '2019-02-10'),
('end_date', '2019-02-10'),
('records',
[OrderedDict([('_data_type', 'PREGNANT'),
('_app_type', 'DAYS_POST')]),
OrderedDict([('_data_type', 'VISION'),
('_app_type', 'DAYS_PRE')])])]))])
def nested(od):
"""Iterates over nested OrderedDict returning nested keys"""
if isinstance(od, OrderedDict):
for k, value in od.items():
yield k
if isinstance(value, (list, OrderedDict)):
yield from nested(value)
if isinstance(od, list):
for value in od:
if isinstance(value, (list, OrderedDict)):
yield from nested(value)
# iterate over the keys, store no duplicates, preserver order of appearance
result, seen = [], set()
for key in nested(ipt['report']):
if key not in seen:
result.append(key)
seen.add(key)
print(result)
Output
['generated_at', 'record_count', 'start_date', 'end_date', 'records', '_data_type', '_app_type']
Upvotes: 2