def get_data_by_dict_path(json_obj, dict_path, include_reverse=False):
    """Traverse a json object by recursively indexing it along a path.

    'json_obj' must be a json object, i.e. a list or dict of list or dicts.
    'dict_path' is a list of str or int, which will be used as indexes.

    If 'include_reverse' is False, then return a subobject, or None if one of
    the index does not exist.
    If 'include_reverse' is True, then return subobject, reverse_path, where
    reverse_path are the subobject encountered during each index. reverse_path
    has the same length as dict_path and reverse_path[0] is json_obj.

    Note that this tolerate string index for arrays if the string is a decimal
    representation of an integer.

    >>> get_data_by_dict_path({"a": ["b", {"c": 5}]}, ["a", 1, "c"])
    5
    >>> get_data_by_dict_path({"a": ["b", {"c": 5}]}, ["a", "0"])
    'b'
    >>> get_data_by_dict_path({"a": ["b", {"c": 5}]}, ["a", "0"], True)
    'b', [{"a": ["b", {"c": 5}]}, ["b", {"c": 5}]]
    """
    reverse_path = []
    for component in dict_path:
        if include_reverse:
            reverse_path.append(json_obj)
        if isinstance(json_obj, list):
            try:
                json_obj = json_obj[int(component)]
            except:
                return None
        else:
            json_obj = json_obj.get(component)
            if json_obj is None:
                return None
    if include_reverse:
        return json_obj, reverse_path
    return json_obj