1

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.

Sri
  • 105
  • 1
  • 9
  • Possible duplicate of [Get a list of all keys in nested dictionary](https://stackoverflow.com/questions/26166910/get-a-list-of-all-keys-in-nested-dictionary) – Georgy Oct 16 '19 at 13:17
  • The key `_data_type` is present two times, but in your result appears only one time. Why? – Dani Mesejo Oct 16 '19 at 13:18

1 Answers1

2

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']
Dani Mesejo
  • 61,499
  • 6
  • 49
  • 76