Accessing YAML data in Python

python, yaml

Solution

The brackets, `[]`, indicate that you have lists of dicts, not just a dict.

For example, `settingsMap['name']` is a list of dicts.

Therefore, you need to select the correct dict in the list using an integer index, before you can select the key in the dict.

So, giving your current data structure, you'd need to use:

settingsMap['name'][1]['categories'][0]['quick'][0]['directory']

Or, revise the underlying YAML data structure.

For example, if the data structure looked like this:

settingsMap = {
    'name':
    {'proj_directory': '/directory/',
     'categories': {'quick': {'directory': 'quick',
                              'description': None,
                              'table_name': 'quick'}},
     'intermediate': {'directory': 'intermediate',
                      'description': None,
                      'table_name': 'intermediate'},
     'research': {'directory': 'research',
                  'description': None,
                  'table_name': 'research'},
     'nomenclature': {'extension': 'nc',
                      'handler': 'script',
                      'filename': {'id': {'type': 'VARCHAR'},
                                   'date': {'type': 'DATE'},
                                   'v': {'type': 'INT'}},
                      'data': {'time': {'variable_name': 'time',
                                        'units': 'minutes since 1-1-1980 00:00 UTC'}}}}}

then you could access the same value as above with

settingsMap['name']['categories']['quick']['directory']
# quick

Problem

I have a YAML file that parses into an object, e.g.: ``` {'name': [{'proj_directory': '/directory/'}, {'categories': [{'quick': [{'directory': 'quick'}, {'description': None}, {'table_name': 'quick'}]}, {'intermediate': [{'directory': 'intermediate'}, {'description': None}, {'table_name': 'intermediate'}]}, {'research': [{'directory': 'research'}, {'description': None}, {'table_name': 'research'}]}]}, {'nomenclature': [{'extension': 'nc'} {'handler': 'script'}, {'filename': [{'id': [{'type': 'VARCHAR'}]}, {'date': [{'type': 'DATE'}]}, {'v': [{'type': 'INT'}]}]}, {'data': [{'time': [{'variable_name': 'time'}, {'units': 'minutes since 1-1-1980 00:00 UTC'}, {'latitude': [{'variable_n... ``` I'm having trouble accessing the data in python and regularly see the error `TypeError: list indices must be integers, not str` I want to be able to access all elements corresponding to `'name'` so to retrieve each data field I imagine it would look something like: ``` import yaml settings_stream = open('file.yaml', 'r') settingsMap = yaml.safe_load(settings_stream) yaml_stream = True print 'loaded settings for: ', for project in settingsMap: print project + ', ' + settingsMap[project]['project_directory'] ``` and I would expect each element would be accessible via something like `['name']['categories']['quick']['directory']` and something a little deeper would just be: `['name']['nomenclature']['data']['latitude']['variable_name']` or am I completely wrong here?

Original source