Formatuj ciąg wyjściowy, wyrównanie do prawej

149

Przetwarzam plik tekstowy zawierający współrzędne x, y, z

     1      128  1298039
123388        0        2
....

każda linia jest podzielona na 3 elementy za pomocą

words = line.split()

Po przetworzeniu danych muszę zapisać współrzędne z powrotem w innym pliku txt, tak aby elementy w każdej kolumnie były wyrównane do prawej (podobnie jak plik wejściowy). Każda linia składa się ze współrzędnych

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

Czy std::setw()w C ++ jest jakiś manipulator, taki jak itp., Który pozwala ustawić szerokość i wyrównanie?

justik
źródło

Odpowiedzi:

230

Wypróbuj to podejście, używając nowszej str.formatskładni :

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

A oto jak to zrobić, używając starej %składni (przydatne w przypadku starszych wersji Pythona, które nie obsługują str.format):

line_new = '%12s  %12s  %12s' % (word[0], word[1], word[2])
Mark Byers
źródło
39
Zwróć uwagę, że „stara” składnia jest bardziej przejrzysta, czytelniejsza i krótsza.
fyngyrz
2
Pomyślałem, że dodam bardziej bezpośredni link niż podany: docs.python.org/2/library/ ...
brw59
48
Na pewno krótszy, nie wiem, co naprawdę oznacza sprzątaczka, ale „łatwiejsze do odczytania” jest tylko dlatego, że wydaje mi się, że jest znajome. Jeśli nie znasz jeszcze jednego z nich, nowy format wydaje się łatwiejszy do odczytania. ".format" do formatowania napisów z pewnością wydaje się bardziej intuicyjny niż procent / modulo. Strzałka w prawo do wyrównania w prawo również wydaje się całkiem intuicyjna.
Mark
2
@Mark Po pierwsze, stary sposób jest bardziej przejrzysty polega na tym, że używa mniejszej liczby znaków. Tak, dzięki znajomości nowy sposób staje się intuicyjny, ale nie jest czystszy i prostszy. Stary sposób jest bardziej intuicyjny dla tych, którzy są przyzwyczajeni do składni, która dociera do nas poprzez czcigodny język C, język wzorowej zwięzłości i precyzji. Jaki jest precedens dla nowej drogi?
Stephen Boston
2
@StephenBoston Czytelność pozostawię ekspertom, ale nowy sposób jest absolutnie czystszy. Pareny nie są już opcjonalne. % można pomylić z operatorem matematycznym (choć mało prawdopodobne w kontekście, ale na pierwszy rzut oka pewne). Stary sposób zawiódłby, gdyby słowo [n] nie było oczekiwanego typu (w tym przypadku ciąg znaków). Nowy sposób nie musi wiedzieć, jaki jest typ przychodzący, zawsze działa. Czyste i proste. Szczerze mówiąc, nigdy nie czułem się komfortowo ze stylem printf (głównie robiłem C z cout).
Zim
53

Można to osiągnąć stosując rjust:

line_new = word[0].rjust(10) + word[1].rjust(10) + word[2].rjust(10)
clwen
źródło
51

Możesz to wyrównać w ten sposób:

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

gdzie >oznacza „ wyrównaj do prawej ” i 8jest szerokością określonej wartości.

A oto dowód:

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


       1      128  1298039
  123388        0        2

Ps. *lineoznacza, że linelista zostanie rozpakowana, więc .format(*line)działa podobnie do .format(line[0], line[1], line[2])(zakładając, że linejest to lista zawierająca tylko trzy elementy).

Tadeck
źródło
18

Oto inny sposób formatowania przy użyciu formatu „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}",
)

Zapewni to następujące dane wyjściowe:

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

To, co tutaj robisz, to mówisz, że pierwsza kolumna ma 15 znaków i jest wyrównana do lewej, a druga kolumna (wartości) ma długość 10 znaków i jest wyrównana do prawej.

Vlad Bezden
źródło
Czy istnieje sposób na sparametryzowanie szerokości formatów? W tym przykładzie, jeśli zdecydujesz się zmienić formatowanie na 20 i 15 szerokości, będzie to wymagało zmiany wielu linii. widths = [15, 10] f"{'Trades:':<width[0]}{cnt:>width[1]}",Chciałbym osiągnąć coś takiego jak powyżej.
Tomasz Sabała
1
Rozumiem! Może ktoś uzna to za pomocne. Potrzebuję do tego jeszcze jednego zagnieżdżonego nawiasu więc:f"{'Trades:':<{width[0]}}{cnt:>{width[1]}}"
Tomasz Sabała
1
Czasami najlepsze odpowiedzi to te, które nie odpowiadają dokładnie na pytanie. Dzięki za to! :)
Brian Wiley
5

Prosta tabela wyników:

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

wynik:

variable a    variable b
      0.33         66.67

% 10.2f: 10 to minimalna długość, a 2 to liczba miejsc dziesiętnych.

Thoran
źródło
1

Aby to zrobić używając f-string i kontrolując liczbę końcowych cyfr:

print(f'A number -> {my_number:>20.5f}')
Nauka to bałagan
źródło