Flattens the given dict into a single-level dict with flattend keys.

    Parameters
    ----------
    dict_obj : dict
        A possibly nested dict.
    separator : str, optional
        The character to use as a separator between keys. Defaults to '.'.
    flatten_lists : bool, optional
        If True, list values are also flattened. False by default.

    Returns
    -------
    dict
        A shallow dict, where no value is a dict in itself, and keys are
        concatenations of original key paths separated with the given
        separator.

    Example
    -------
    >>> dicti = {'a': 1, 'b': {'g': 4, 'o': 9}, 'x': [4, 'd']}
    >>> flat = flatten_dict(dicti)
    >>> sorted(flat.items())
    [('a', 1), ('b.g', 4), ('b.o', 9), ('x.0', 4), ('x.1', 'd')]

def flatten_dict(dict_obj, separator='.', flatten_lists=False):
    """Flattens the given dict into a single-level dict with flattend keys.

    Parameters
    ----------
    dict_obj : dict
        A possibly nested dict.
    separator : str, optional
        The character to use as a separator between keys. Defaults to '.'.
    flatten_lists : bool, optional
        If True, list values are also flattened. False by default.

    Returns
    -------
    dict
        A shallow dict, where no value is a dict in itself, and keys are
        concatenations of original key paths separated with the given
        separator.

    Example
    -------
    >>> dicti = {'a': 1, 'b': {'g': 4, 'o': 9}, 'x': [4, 'd']}
    >>> flat = flatten_dict(dicti)
    >>> sorted(flat.items())
    [('a', 1), ('b.g', 4), ('b.o', 9), ('x.0', 4), ('x.1', 'd')]
    """
    reducer = _get_key_reducer(separator)
    flat = {}

    def _flatten_key_val(key, val, parent):
        flat_key = reducer(parent, key)
        try:
            _flatten(val, flat_key)
        except TypeError:
            flat[flat_key] = val

    def _flatten(d, parent=None):
        try:
            for key, val in d.items():
                _flatten_key_val(key, val, parent)
        except AttributeError:
            if isinstance(d, (str, bytes)):
                raise TypeError
            for i, value in enumerate(d):
                _flatten_key_val(str(i), value, parent)
    _flatten(dict_obj)
    return flat