list indices must be integers python nested dictionaries
Question: In python 3, I need a function to dynamically return a value from a nested
key.

    
    
    nesteddict = {'a':'a1','b':'b1','c':{'cn':'cn1'}}
    print(nesteddict['c']['cn']) #gives cn1
    
    def nestedvalueget(keys):
        print(nesteddict[keys])
    
    nestedvalueget(['n']['cn'])
    

How should nestedvalueget be written?

I'm not sure the title is properly phrased, but I'm not sure how else to best
describe this.


Answer: If you want to traverse dictionaries, use a loop:

    
    
    def nestedvalueget(*keys):
        ob = nesteddict
        for key in keys:
            ob = ob[key]
        return ob
    

or use
[`functools.reduce()`](http://docs.python.org/3/library/functools.html#functools.reduce):

    
    
    from functools import reduce
    from operator import getitem
    
    def nestedvalueget(*keys):
        return reduce(getitem, keys, nesteddict)
    

then use either version as:

    
    
    nestedvalueget('c', 'cn')
    

Note that either version takes a variable number of arguments to let you pas 0
or more keys as positional arguments.

Demos:

    
    
    >>> nesteddict = {'a':'a1','b':'b1','c':{'cn':'cn1'}}
    >>> def nestedvalueget(*keys):
    ...     ob = nesteddict
    ...     for key in keys:
    ...         ob = ob[key]
    ...     return ob
    ... 
    >>> nestedvalueget('c', 'cn')
    'cn1'
    >>> from functools import reduce
    >>> from operator import getitem
    >>> def nestedvalueget(*keys):
    ...     return reduce(getitem, keys, nesteddict)
    ... 
    >>> nestedvalueget('c', 'cn')
    'cn1'
    

And to clarify your error message: You passed the expression `['n']['cn']` to
your function call, which defines a list with one element (`['n']`), which you
then try to index with `'cn'`, a string. List indices can only be integers:

    
    
    >>> ['n']['cn']
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: list indices must be integers, not str
    >>> ['n'][0]
    'n'
    

