使用.format()格式化带有字段宽度参数的列表

我最近(终于?)开始使用zip(),并且对此可能有一个模糊的问题。

给定

res = ['Irene Adler', 35,  24.798]

(1) print('{0[0]:10s} {0[1]:5d} {0[2]:.2f}'.format(res))
(2) print('{:{}s} {:{}d} {:{}f}'.format(res[0], 10, res[1], 5, res[2], .2))

工作出色,并且都可以打印:

Irene Adler    35 24.80
Irene Adler    35 24.80

我不知道我可以像(1)中那样处理列表,这很简洁。 一世以前曾使用过旧的zip()格式了解过字段宽度参数(2)。

我的问题是想要做这样的事情,将(1)和(2)结合起来:

(3) print('{0[0]:{}s} {0[1]:{}d} {0[2]:{}f}'.format(res, 10, 5, .2))

但是,我无法做到这一点,也无法弄清楚如果可能的话,从文档中获取。 只是很好提供要打印的列表以及width的参数。

顺便说一句,我也尝试了这个(没有运气):

args = (10, 5, .2)
(4) print('{0[0]:{}s} {0[1]:{}d} {0[2]:{}f}'.format(res, args))

在这两种情况下,我得到:

D:\Users\blabla\Desktop>python tmp.py
Traceback (most recent call last):
  File "tmp.py", line 27, in <module>
    print('{0[0]:{}s} {0[1]:{}d} {0[2]:{}f}'.format(res, 10, 5, .2))
ValueError: cannot switch from manual field specification to automatic field numbering

D:\Users\blabla\Desktop>python tmp.py
Traceback (most recent call last):
  File "tmp.py", line 35, in <module>
    print('{0[0]:{}s} {0[1]:{}d} {0[2]:{}f}'.format(res, args))
ValueError: cannot switch from manual field specification to automatic field numbering

我还尝试使用zip()将两个序列组合在一起而没有运气。

我的问题是:

我可以指定要进行有效打印的列表吗?未能在(3)和(4)中完成(显然,如果可能的话,我是没有使用正确的语法),如果是的话,怎么办?

Levon asked 2020-06-29T18:55:51Z
2个解决方案
64 votes

错误讯息

ValueError: cannot switch from manual field specification to automatic field numbering

几乎全部说明了这一点:您需要在任何地方提供明确的字段索引,并且

print('{0[0]:{1}s} {0[1]:{2}d} {0[2]:{3}f}'.format(res, 10, 5, .2))

工作良好。

Sven Marnach answered 2020-06-29T18:56:16Z
2 votes

如果要使用*,则可以在格式字符串中指定所有索引,如下所示:

>>> print('{0[0]:{1[0]}s} {0[1]:{1[1]}d} {0[2]:{1[2]}f}'.format(res, args))
Irene Adler    35 24.80

但是,如果要使格式字符串不带索引,则可以创建连续对的元组*

这是通过以下成语完成的:

>>> sum(zip(res, args), ())
('Irene Adler', 10, 35, 5, 24.798, 0.2)

现在,您可以将其传递给简化的格式字符串(通过*-argument):

>>> fmt = sum(zip(res, args), ())
>>> print('{:{}s} {:{}d} {:{}f}'.format(*fmt))
('Irene Adler', 10, 35, 5, 24.798, 0.2)

当然,这可以一行完成:

>>> print('{:{}s} {:{}d} {:{}f}'.format(*sum(zip(res, args), ())))
Irene Adler    35 24.80

为了使其可读,我将转换命名为:

def flat_pairs(iterable1, iterable2):
    return sum(zip(iterable1, iterable2), ())

# (...)

>>> print('{:{}s} {:{}d} {:{}f}'.format(*flat_pairs(res, args)))
Irene Adler    35 24.80

我认为最后一个是在可读性,便利性之间进行合理的权衡,当然,这是炫耀您的Python思维方式,这是玩这类东西的主要动机。

Tomasz Gandor answered 2020-06-29T18:57:03Z
translate from https://stackoverflow.com:/questions/10875121/using-format-to-format-a-list-with-field-width-arguments