Использование .format () для форматирования списка с аргументами ширины поля

Я недавно (наконец-то?) Начал использовать.format() а также есть, возможно, немного неясный вопрос об этом.

Дано

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), что является аккуратным. я видел аргументы ширины поля (2) со старым% форматирование раньше.

Мой вопрос о желании сделать что-то вроде этого, который сочетает в себе (1) и (2):

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

Однако я не могу сделать это, и я не смог выяснить, из документации, если это вообще возможно. Было бы неплохо просто предоставить список для печати и аргументы для ширины.

Кстати, я тоже попробовал это (без удачи):

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() объединить две последовательности без удачи.

My question is:

Могу ли я указать список для печати, эффективно делая то, что я пытался неудачно сделать в (3) и (4) (ясно, если это возможно, я 'm не используя правильный синтаксис) и если да, то как?

Ответы на вопрос(2)

Решение Вопроса

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))

работает отлично.

 Levon04 июн. 2012 г., 03:38
Спасибо, Свен, не уверен, почему я этого не понял. Я также понял, что я могу это:args = (10, 5, .2) а потомprint('{0[0]:{1}s} {0[1]:{2}d} {0[2]:{3}f}'.format(res, *args)) .. очень хорошо.

.format(res, args)Вы можете указать все индексы в строке формата следующим образом:

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

Но если вы хотите сделать строку формата без индексов, вы можете создать кортеж последовательных пар(res[0], args[0], ... , res[-1], args[-1]).

Это сделано с помощью этой идиомы:

>>> 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

Я думаю, что последний является разумным компромиссом между удобочитаемостью, удобством и, конечно же, демонстрацией вашего Pythonic мышления, которое является основной мотивацией для игры с такими вещами.

Ваш ответ на вопрос