def deflatten(d, sep='.', maxdepth=-1):
    """Build a nested dict from a flat dict respecting a separator.

    >>> d_in = {'a': 1, 'c': {'a': 2, 'b': {'x': 5, 'y' : 10}}, 'd': [1, 2, 3]}
    >>> d = flatten(d_in)
    >>> for k, v in d.items(): print(k, v)
    a 1
    c.a 2
    c.b.x 5
    c.b.y 10
    d [1, 2, 3]
    >>> deflatten(d)
    {'a': 1, 'c': {'a': 2, 'b': {'x': 5, 'y': 10}}, 'd': [1, 2, 3]}
    >>> deflatten(d, maxdepth=1)
    {'a': 1, 'c': {'a': 2, 'b.x': 5, 'b.y': 10}, 'd': [1, 2, 3]}
    >>> deflatten(d, maxdepth=0)
    {'a': 1, 'c.a': 2, 'c.b.x': 5, 'c.b.y': 10, 'd': [1, 2, 3]}
    >>> d = flatten(d_in, sep='_')
    >>> for k, v in d.items(): print(k, v)
    a 1
    c_a 2
    c_b_x 5
    c_b_y 10
    d [1, 2, 3]
    >>> deflatten(d, sep='_')
    {'a': 1, 'c': {'a': 2, 'b': {'x': 5, 'y': 10}}, 'd': [1, 2, 3]}
    >>> deflatten({('a', 'b'): 'd', ('a', 'c'): 'e'}, sep=None)
    {'a': {'b': 'd', 'c': 'e'}}
    >>> deflatten({'a.b': 1, 'a': 2})
    Traceback (most recent call last):
      ...
    AssertionError: Conflicting keys! ('a',)
    >>> deflatten({'a': 1, 'a.b': 2})
    Traceback (most recent call last):
      ...
    AssertionError: Conflicting keys! ('a', 'b')

    """
    ret = {}
    if sep is not None:
        d = {
            tuple(k.split(sep, maxdepth)): v for k, v in d.items()
        }

    for keys, v in d.items():
        sub_dict = ret
        for sub_key in keys[:-1]:
            if sub_key not in sub_dict:
                sub_dict[sub_key] = {}
            assert isinstance(sub_dict[sub_key], dict), (
                f'Conflicting keys! {keys}'
            )
            sub_dict = sub_dict[sub_key]
        assert keys[-1] not in sub_dict, f'Conflicting keys! {keys}'
        sub_dict[keys[-1]] = v
    return ret