На самом деле вы можете использовать двухпроходный подход , чтобы сначала получить правильные длины.В соответствии с вашим примером с четырьмя полями в строке, ниже показана основная идея, которую вы можете использовать.
Ниже приведен пример двухпроходного подхода: сначала получить максимальную длину для каждого поля, а другой -чтобы сделать то, что вы делаете в данный момент (с расчетной, а не фиксированной длиной):
# Can set MINIMUM lengths here if desired, eg: lengths = [10, 0, 41, 7]
lengths = [0] * 4
fmtstr = None
for pass in range(2):
for i in range(len(list_l)):
if pass == 0:
# First pass sets lengths as per data.
for field in range(4):
lengths[field] = max(lengths[field], len(list_l[i][field])
else:
# Second pass prints the data.
# First, set format string if not yet set.
if fmtstr is None:
fmtstr = '|'
for item in lengths:
fmtstr += '{:^%ds}|' % (item)
# Now print item (and header stuff if first item).
if i == 0: print(h_dashes)
print(fmtstr.format(list_l[i][0].upper(), list_l[i][1].upper(), list_l[i][2].upper(), list_l[i][3].upper()))
if i == 0: print(h_dashes)
Построение строки формата выполняется при первой обработке элемента на втором проходе.
Он делает это, беря коллекцию, подобную [31,41,59]
, и выдает строку:
|{:^31s}|{:^41s}|{:^59s}|
Нет смысла использовать все эти спецификаторы формата {:^1s}
, когда |
не на самом деле изменяющийся элемент - вы также можете закодировать его непосредственно в строку формата.