Формат вихідного рядка, правильне вирівнювання


149

Я обробляю текстовий файл, що містить координати x, y, z

     1      128  1298039
123388        0        2
....

кожен рядок розділений на 3 елементи за допомогою

words = line.split()

Після обробки даних мені потрібно записати координати назад в інший файл txt, щоб елементи в кожному стовпці були вирівняні вправо (як і вхідний файл). Кожна лінія складається з координат

line_new = words[0]  + '  ' + words[1]  + '  ' words[2].

Чи є std::setw()в C ++ якийсь маніпулятор на зразок тощо, що дозволяє встановити ширину та вирівнювання?

Відповіді:


230

Спробуйте цей підхід, використовуючи новіший str.formatсинтаксис :

line_new = '{:>12}  {:>12}  {:>12}'.format(word[0], word[1], word[2])

Ось як це зробити за допомогою старого %синтаксису (корисно для старих версій Python, які не підтримують str.format):

line_new = '%12s  %12s  %12s' % (word[0], word[1], word[2])

39
Зауважте, як "старий" синтаксис чистіший, легший для читання та коротший.
fyngyrz

2
Я думав, що додаю більш пряме посилання, ніж надане: docs.python.org/2/library/…
brw59

48
Коротше, напевно, я не знаю, що насправді означає очищувач, але "легше читати" це лише тому, що він знайомий, я думаю. Якщо ви вже не знайомі з одним із них, новий формат здається легшим для читання. ".формат" для форматування рядків, звичайно, здається більш інтуїтивним, ніж відсоток / модуль. Стрілка праворуч для правого вирівнювання теж здається досить інтуїтивно зрозумілою.
Марк

2
@Mark Один із способів, коли старий спосіб є чистішим, полягає в тому, що він використовує менше символів. Так, при знайомстві новий спосіб стає інтуїтивно зрозумілим, але він не чистіший і простіший. Старий спосіб є більш інтуїтивним для тих, хто звик до синтаксису, який приходить до нас через поважну мову С, мовою зразкової стислість та точність. Який прецедент є для нового шляху?
Стівен Бостон

2
@StephenBoston Я залишу читабельність для експертів, але новий спосіб абсолютно чистіший. Парени більше не є обов'язковими. % можна плутати з математичним оператором (хоча і не вірогідним у контексті, але на перший погляд впевненим). Старий спосіб не зможе, якщо слово [n] не має очікуваного типу (рядок у цьому випадку). Новий спосіб не повинен знати, що таке вхідний тип, він завжди працює. Чисто і просто. Справедливо кажучи, мені ніколи не подобалося стилю printf (я здебільшого робив C з cout).
Зім

53

Це можна досягти, використовуючи rjust:

line_new = word[0].rjust(10) + word[1].rjust(10) + word[2].rjust(10)

51

Ви можете вирівняти його так:

print('{:>8} {:>8} {:>8}'.format(*words))

де >означає " вирівняти праворуч " і 8є шириною для конкретного значення.

І ось доказ:

>>> for line in [[1, 128, 1298039], [123388, 0, 2]]:
    print('{:>8} {:>8} {:>8}'.format(*line))


       1      128  1298039
  123388        0        2

Пс. *lineозначає, що lineсписок буде розпакований, тому .format(*line)працює аналогічно .format(line[0], line[1], line[2])(припустимо line, що це список лише з трьома елементами).



18

Ось ще один спосіб, як можна форматувати, використовуючи формат 'f-string':

print(
    f"{'Trades:':<15}{cnt:>10}",
    f"\n{'Wins:':<15}{wins:>10}",
    f"\n{'Losses:':<15}{losses:>10}",
    f"\n{'Breakeven:':<15}{evens:>10}",
    f"\n{'Win/Loss Ratio:':<15}{win_r:>10}",
    f"\n{'Mean Win:':<15}{mean_w:>10}",
    f"\n{'Mean Loss:':<15}{mean_l:>10}",
    f"\n{'Mean:':<15}{mean_trd:>10}",
    f"\n{'Std Dev:':<15}{sd:>10}",
    f"\n{'Max Loss:':<15}{max_l:>10}",
    f"\n{'Max Win:':<15}{max_w:>10}",
    f"\n{'Sharpe Ratio:':<15}{sharpe_r:>10}",
)

Це забезпечить такий вихід:

Trades:              2304
Wins:                1232
Losses:              1035
Breakeven:             37
Win/Loss Ratio:      1.19
Mean Win:           0.381
Mean Loss:         -0.395
Mean:               0.026
Std Dev:             0.56
Max Loss:          -3.406
Max Win:             4.09
Sharpe Ratio:      0.7395

Що ви робите тут, ви говорите, що перший стовпець має 15 символів, і це лівовиправдано, а другий стовпець (значення) - 10 символів і він правильний.


Чи є спосіб параметризувати ширину форматів? У цьому прикладі, якщо ви вирішили змінити форматування на 20 і 15 ширини, потрібно змінити кілька рядків. widths = [15, 10] f"{'Trades:':<width[0]}{cnt:>width[1]}",Я хотів би досягти чогось, як вище.
Томаш

1
Зрозумів! Можливо, комусь це стане в нагоді. Для цього мені потрібні ще одні вкладені дужки, щоб:f"{'Trades:':<{width[0]}}{cnt:>{width[1]}}"
Томаш

1
Іноді найкращі відповіді - це ті, які не відповідають на точне запитання. Дякую за це! :)
Брайан Вілі

5

Просте табулювання результату:

a = 0.3333333
b = 200/3
print("variable a    variable b")
print("%10.2f    %10.2f" % (a, b))

вихід:

variable a    variable b
      0.33         66.67

% 10.2f: 10 - мінімальна довжина, а 2 - кількість десяткових знаків.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.