def populate_nested_dictionary(dictionary, key_list, types=[]):
    """
    For each key k_i in key_list, make sure that
    dictionary[k_0][k_1][k_2]...[k_i] exists, creating objects of the
    appropriate type in each sub-dictionary as needed.

    If types is specified, then dictionary[key_list[i]] should point to an
    object of type types[i] for all i

    returns the element corresponding to dictionary[k_0][k_1]...[k_{n-1}] where
    n is the size of key_list
    """

    if len(key_list) > 0:
        if key_list[0] not in dictionary:
            if len(types) > 0:
                dictionary[key_list[0]] = types[0]()
            else:
                dictionary[key_list[0]] = {}

        return populate_nested_dictionary(dictionary[key_list[0]], key_list[1:],
                                          types[1:])
    else:
        return dictionary