Formats a list and a dictionary, manages unkown keys

    It works like :meth:`string.Formatter.vformat` except that it accepts a defvalue for not matching keys.
    Defvalue can be a callable that will receive the requested key as argument and return a string

    Args:
        format_string (str): Same format string as for :meth:`str.format`
        lst (dict) : the list to format
        dct (dict) : the dict to format
        defvalue (str or callable): the default value to display when the data is not in the dict

    Examples:

        >>> d = {'count': '32591', 'soft': 'textops'}
        >>> l = ['Eric','Guido']
        >>> eformat('{0} => {soft} : {count} dowloads',l,d)
        'Eric => textops : 32591 dowloads'
        >>> eformat('{2} => {software} : {count} dowloads',l,d,'N/A')
        'N/A => N/A : 32591 dowloads'
        >>> eformat('{2} => {software} : {count} dowloads',l,d,lambda k:'unknown_tag_%s' % k)
        'unknown_tag_2 => unknown_tag_software : 32591 dowloads'

def eformat(format_str,lst,dct,defvalue='-'):
    """ Formats a list and a dictionary, manages unkown keys

    It works like :meth:`string.Formatter.vformat` except that it accepts a defvalue for not matching keys.
    Defvalue can be a callable that will receive the requested key as argument and return a string

    Args:
        format_string (str): Same format string as for :meth:`str.format`
        lst (dict) : the list to format
        dct (dict) : the dict to format
        defvalue (str or callable): the default value to display when the data is not in the dict

    Examples:

        >>> d = {'count': '32591', 'soft': 'textops'}
        >>> l = ['Eric','Guido']
        >>> eformat('{0} => {soft} : {count} dowloads',l,d)
        'Eric => textops : 32591 dowloads'
        >>> eformat('{2} => {software} : {count} dowloads',l,d,'N/A')
        'N/A => N/A : 32591 dowloads'
        >>> eformat('{2} => {software} : {count} dowloads',l,d,lambda k:'unknown_tag_%s' % k)
        'unknown_tag_2 => unknown_tag_software : 32591 dowloads'
    """
    return vformat(format_str,DefaultList(defvalue,lst),DefaultDict(defvalue,dct))