Print string left aligned with fixed width and suffix
Question: Using Pythons string formatting, is there a nice way to add a suffix to a left
aligned string that is padded to a fixed size?

I want to print a list of key-value-pairs in the following formatting:

    
    
    a_key:        23
    another_key:  42
    ...
    

The problem is the ':'. The best solution I found so far is to append the ':'
to the key name:

    
    
    print "{:<20}  {}".format(key+':', value)
    

But I think this is a rather ugly solution, as it diminishes the separation of
formatting and values. Is it possible to achieve this directly in the format
specification?

What I am looking for is something like this:

    
    
    print "{do something here}  {}".format(key, value)
    


Answer: You cannot change `"".format()` as it is a built-in but if it is acceptable to
provide the string and parameters to a method:

    
    
    print(kf.format("{:t{}}  {}", key, ':', value))
    

you can do so by subclassing `string.Formatter` to allow empty format fields
and provide a special type handler `t`:

    
    
    from string import Formatter
    import sys
    
    if sys.version_info < (3,):
        int_type = (int, long)
    else:
        int_type = (int)
    
    class TrailingFormatter(Formatter):
    
        def vformat(self, *args):
            self._automatic = None
            return super(TrailingFormatter, self).vformat(*args)
    
        def get_value(self, key, args, kwargs):
            if key == '':
                if self._automatic is None:
                    self._automatic = 0
                elif self._automatic == -1:
                    raise ValueError("cannot switch from manual field specification "
                                     "to automatic field numbering")
                key = self._automatic
                self._automatic += 1
            elif isinstance(key, int_type):
                if self._automatic is None:
                    self._automatic = -1
                elif self._automatic != -1:
                    raise ValueError("cannot switch from automatic field numbering "
                                     "to manual field specification")
            return super(TrailingFormatter, self).get_value(key, args, kwargs)
    
        def format_field(self, value, spec):
            if len(spec) > 1 and spec[0] == 't':
                value = str(value) + spec[1]  # append the extra character
                spec = spec[2:]
            return super(TrailingFormatter, self).format_field(value, spec)
    
    kf = TrailingFormatter()
    w = 20
    ch = ':'
    x = dict(a_key=23, another_key=42)
    
    for k in sorted(x):
        v = x[k]
        print(kf.format('{:t{}<{}} {}', k, ch, w, v))
    

gives you:

    
    
     a_key:               23
     another_key:         42
    

You can of course hardcode the `ch`, and `w` values:

    
    
        print(kf.format('{:t:<20} {}', k, v))
    

for better readability, but less flexibility.

* * *

A backport of the Python 3.4 string.Formatter() that includes a bugfix for
versions (at least) up to 3.5.0rc1, that includes this code is now available
on [PyPI](https://pypi.python.org/pypi/string_formatter)

