Accessing YAML data in Python
Question: 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?


Answer: 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
    

