Convert a value to a list of specified length.

    If the input is too short, fill it with its last element.

    Parameters
    ----------
    xs
        Input list or value.
    length : `int`
        Output list length.
    copy : `bool`, optional
        Deep copy the last element to fill the list (default: False).

    Returns
    -------
    `list`

    Raises
    ------
    ValueError
        If `xs` is empty and `length` > 0

    Examples
    --------
    >>> fill(0, 3)
    [0, 0, 0]
    >>> fill((x ** 2 for x in range(3)), 1)
    [0]
    >>> x = [{'x': 0}, {'x': 1}]
    >>> y = fill(x, 4)
    >>> y
    [{'x': 0}, {'x': 1}, {'x': 1}, {'x': 1}]
    >>> y[2] is y[1]
    True
    >>> y[3] is y[2]
    True
    >>> y = fill(x, 4, True)
    >>> y
    [{'x': 0}, {'x': 1}, {'x': 1}, {'x': 1}]
    >>> y[2] is y[1]
    False
    >>> y[3] is y[2]
    False

def fill(xs, length, copy=False):
    """Convert a value to a list of specified length.

    If the input is too short, fill it with its last element.

    Parameters
    ----------
    xs
        Input list or value.
    length : `int`
        Output list length.
    copy : `bool`, optional
        Deep copy the last element to fill the list (default: False).

    Returns
    -------
    `list`

    Raises
    ------
    ValueError
        If `xs` is empty and `length` > 0

    Examples
    --------
    >>> fill(0, 3)
    [0, 0, 0]
    >>> fill((x ** 2 for x in range(3)), 1)
    [0]
    >>> x = [{'x': 0}, {'x': 1}]
    >>> y = fill(x, 4)
    >>> y
    [{'x': 0}, {'x': 1}, {'x': 1}, {'x': 1}]
    >>> y[2] is y[1]
    True
    >>> y[3] is y[2]
    True
    >>> y = fill(x, 4, True)
    >>> y
    [{'x': 0}, {'x': 1}, {'x': 1}, {'x': 1}]
    >>> y[2] is y[1]
    False
    >>> y[3] is y[2]
    False
    """
    if isinstance(xs, list) and len(xs) == length:
        return xs

    if length <= 0:
        return []

    try:
        xs = list(islice(xs, 0, length))
        if not xs:
            raise ValueError('empty input')
    except TypeError:
        xs = [xs]

    if len(xs) < length:
        if copy:
            last = xs[-1]
            xs.extend(deepcopy(last) for _ in range(length - len(xs)))
        else:
            xs.extend(islice(repeat(xs[-1]), 0, length - len(xs)))

    return xs