使用固定宽度和后缀将字符串左对齐打印

4
使用Python字符串格式化,有没有一种好的方法可以添加后缀到左对齐的字符串,并将其填充到固定大小?
我想以以下格式打印键值对列表:
a_key:        23
another_key:  42
...

问题在于“:”符号。目前我找到的最好解决方案是将“:”附加到键名后面:
print "{:<20}  {}".format(key+':', value)

但我认为这是一个相当丑陋的解决方案,因为它削弱了格式和值之间的分离。是否可以直接在格式规范中实现这一点?

我想要的是像这样的东西:

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

1
你看过这个吗?https://dev59.com/32gv5IYBdhLWcg3wHdJ_#10837046 - Adeeb
@Adeeb:那个问题并没有涵盖我想要添加的后缀。 - luator
你想要后缀紧跟在关键文本之后,还是当关键文本比分配的空间小时,想要它在剩余空间之后?在这两个选项中,你想选择哪一个?http://paste.ubuntu.com/10404650/ - Adeeb
@Adeeb:我想让它紧跟在关键词后面(请看我的示例),因此填充应该在后缀之后添加。 - luator
1
我认为 print "{:<20} {}".format(key+':', value) 很好。 - martineau
2个回答

2
您不能更改"".format(),因为它是内置的,但如果可以向方法提供字符串和参数,则可以接受:
print(kf.format("{:t{}}  {}", key, ':', value))

你可以通过子类化string.Formatter来允许空格式字段,并提供一个特殊的类型处理程序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))

给你:
 a_key:               23
 another_key:         42

当然,你可以硬编码 chw 的值:
    print(kf.format('{:t:<20} {}', k, v))

为了更好的可读性,但牺牲了一定的灵活性。
Python 3.4的字符串格式化程序的后移版本,包括对版本(至少)到3.5.0rc1的错误修复,包含此代码的现在可在PyPI上获得。

比我预想的要复杂得多,但它能够工作,所以谢谢 :)。 - luator
是的,如果你可以简单地在内置字符串上打上补丁然后调用"...".altformat()就会更好,但不幸的是你不能这样做。 - Anthon

0
这是一种方法:
d = {'a_key': 23, 'another_key': 42}

for key, value in d.items():
    print '{}: {:<{width}} {}'.format(key, '', value, width=20-len(str(key)))

输出:

another_key:           42
a_key:                 23

另一个选择是:

    print '{}:{}{}'.format(key, ' '*(20-len(str(key))), value)

这是可行的,但它仍然存在格式和数据混合的缺陷。我希望有一种方法可以在不必添加任何内容到 .format(...) 部分的情况下实现这一点。 - luator

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接