Sri
Sri

Reputation: 105

How to get all keys from nested Ordered dictionary

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

Answers (1)

Dani Mesejo
Dani Mesejo

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

Related Questions