Как сделать так, чтобы следующий оператор печати занимал одинаковое количество пробелов для каждой части строки? - PullRequest
0 голосов
/ 24 июня 2018

Как заставить следующий оператор печати занимать одинаковое количество места для каждой порции (эпоха, время, потеря и т. Д.).В настоящее время они не согласованы, поскольку иногда некоторые значения с плавающей запятой могут занимать 5 или 6 пробелов (например, 10.345, 2.123).

print('Epoch: [{0}][{1}/{2}]\t'
      'Time: {batch_time.val:.3f} ({batch_time.avg:.3f})\t'
      'Loss: {loss.val:.4f} ({loss.avg:.4f})\t'
      'Prec@1: {top1.val:.3f}% ({top1.avg:.3f}%)\t'
      'Prec@5: {top5.val:.3f}% ({top5.avg:.3f}%)'.format(
       epoch, i, len(data_loader), batch_time=batch_time,
       loss=losses, top1=top1, top5=top5))

Пример:

Epoch: [4][90/1770] | Time: 0.315 (0.321) | Loss: 1.5111 (1.6552) | Prec@1: 72.266% (67.943%) | Prec@5: 84.375% (83.001%)
Epoch: [4][100/1770] | Time: 0.314 (0.320) | Loss: 1.6079 (1.6558) | Prec@1: 70.312% (67.965%) | Prec@5: 84.766% (82.990%)

Как видите, интервалы в каждом разделе не согласованы.Предварительное добавление пробелов не работает, потому что количество добавляемых пробелов должно быть различным в зависимости от длины значений (90/1770 против 100/1770).

Я понимаю, что могу сделать {:5.3f}в формате print, но проблема с моим оператором print заключается в том, что некоторые являются фиксированными словами, такими как «Epoch», а некоторые являются переменными значениями.Как мне поступить с таким делом?Мне нужно, чтобы весь блок соответствовал не только значениям.

Ответы [ 2 ]

0 голосов
/ 24 июня 2018

Вы также можете играть с 'center', 'rjust' и 'ljust':

In [23]: for a,b,c,d in ( (4,90,1770,0.315), (4,100,1770,0.314)):
    ...:     print("Epoch: "+f"[{a}][{b}/{c}]".center(15)+"| Time: "+f"{d:.3f}".center(8)+"|")
    ...:     

Epoch:   [4][90/1770] | Time:  0.315  |
Epoch:  [4][100/1770] | Time:  0.314  |
0 голосов
/ 24 июня 2018

Вы уже знаете, как добавить ширину к поплавкам:

Я понимаю, что могу сделать {: 5.3f} в формате печати

Вы можете сделать то же самое с целыми числами или любым другим типом.

print('Epoch: [{0:1}][{1:3}/{2:4}]\t'
      'Time: {batch_time.val:5.3f} ({batch_time.avg:5.3f})\t'
      # and so on

То, что {1:3} означает, что 90 будет отображаться с пробелом перед ним, например:

Epoch: [4][ 90/1770] | Time: 0.315 (0.321) | Loss: 1.5111 (1.6552) | Prec@1: 72.266% (67.943%) | Prec@5: 84.375% (83.001%)

Так что это будет соответствовать следующей строке:

Epoch: [4][100/1770] | Time: 0.314 (0.320) | Loss: 1.6079 (1.6558) | Prec@1: 70.312% (67.965%) | Prec@5: 84.766% (82.990%)

Если вы не читали документацию для Мини-языка спецификаций формата и просто гадаете, как вы можете изменить образцы, найденные в произвольном онлайн-коде, в надежде, что они сделают то, что вы хотите , прочитайте документы. Все довольно просто.


Вы также говорите:

проблема с моим оператором печати заключается в том, что некоторые являются фиксированными словами, такими как "Эпоха"

Фиксированные строки не кажутся проблемой в первую очередь.

Если они есть, вы можете сделать их одинаковой ширины, просто добавив пробелы вручную.

Если вы действительно хотите, вы можете сохранить эти фиксированные строки в переменных и вместо них добавить поля формата для них, так что у вас есть куда добавить поле ширины:

print('{epoch_label:6}: [{0:1}][{1:3}/{2:4}]\t'
      '{time_label:6}: {batch_time.val:5.3f} ({batch_time.avg:5.3f})\t'
      # etc.
      loss=losses, top1=top1, top5=top5, 
      epoch_label='Epoch', time_label='Time'))

… но это выглядит глупо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...