Formatieren Sie die Ausgabezeichenfolge und richten Sie sie nach rechts aus

148

Ich verarbeite eine Textdatei mit den Koordinaten x, y, z

     1      128  1298039
123388        0        2
....

Jede Zeile wird mit in 3 Elemente unterteilt

words = line.split()

Nach der Verarbeitung der Daten muss ich die Koordinaten in eine andere txt-Datei zurückschreiben, damit die Elemente in jeder Spalte rechts ausgerichtet sind (sowie die Eingabedatei). Jede Linie besteht aus den Koordinaten

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

Gibt es std::setw()in C ++ einen Manipulator wie usw., mit dem die Breite und Ausrichtung eingestellt werden kann?

justik
quelle

Antworten:

229

Versuchen Sie diesen Ansatz mit der neueren str.formatSyntax :

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

Und so geht's mit der alten %Syntax (nützlich für ältere Versionen von Python, die dies nicht unterstützen str.format):

line_new = '%12s  %12s  %12s' % (word[0], word[1], word[2])
Mark Byers
quelle
39
Beachten Sie, dass die "alte" Syntax sauberer, leichter zu lesen und kürzer ist.
Fyngyrz
2
Ich dachte, ich würde einen direkteren Link als den bereitgestellten hinzufügen
brw59
47
Sicher kürzer, ich weiß nicht, was Reiniger wirklich bedeutet, aber "leichter zu lesen" ist nur, weil es vertraut ist, denke ich. Wenn Sie mit einem von ihnen noch nicht vertraut sind, scheint das neue Format leichter zu lesen zu sein. ".format" für die Formatierung von Zeichenfolgen scheint sicherlich intuitiver zu sein als Prozent / Modulo. Der rechte Pfeil für die rechte Ausrichtung scheint auch ziemlich intuitiv zu sein.
Mark
2
@Mark Ein Weg, wie der alte Weg sauberer ist, ist, dass weniger Zeichen verwendet werden. Ja, mit Vertrautheit wird der neue Weg intuitiv, aber er ist nicht sauberer und einfacher. Der alte Weg ist intuitiver für diejenigen, die an die Syntax gewöhnt sind, die uns durch die ehrwürdige C-Sprache, eine Sprache von beispielhafter Prägnanz und Präzision, einfällt. Welchen Präzedenzfall gibt es für den neuen Weg?
Stephen Boston
2
@ StephenBoston Ich überlasse die Lesbarkeit den Experten, aber der neue Weg ist absolut sauberer. Parens sind nicht mehr optional. % kann mit einem mathematischen Operator verwechselt werden (allerdings nicht wahrscheinlich im Kontext, aber auf einen Blick sicher). Der alte Weg würde fehlschlagen, wenn das Wort [n] nicht vom erwarteten Typ ist (in diesem Fall Zeichenfolge). Der neue Weg muss nicht wissen, was der eingehende Typ ist, er funktioniert immer. Sauber und einfach. Um fair zu sein, ich habe mich nie mit dem Printf-Stil vertraut gemacht (ich habe meistens C mit Cout gemacht).
Zim
53

Dies kann erreicht werden durch rjust:

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

Sie können es so ausrichten:

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

Dabei >bedeutet " nach rechts ausrichten " und 8ist die Breite für einen bestimmten Wert.

Und hier ist ein Beweis:

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


       1      128  1298039
  123388        0        2

Ps. *linebedeutet, dass die lineListe entpackt wird und daher .format(*line)ähnlich funktioniert .format(line[0], line[1], line[2])(vorausgesetzt, es linehandelt sich um eine Liste mit nur drei Elementen).

Tadeck
quelle
27

Ich mag eine neue wörtliche String-Interpolation in Python 3.6+ sehr:

line_new = f'{word[0]:>12}  {word[1]:>12}  {word[2]:>12}'

Referenz: PEP 498 - Literal String Interpolation

dmitry_romanov
quelle
18

Hier ist eine andere Möglichkeit, wie Sie mit dem 'f-string'-Format formatieren können:

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}",
)

Dies liefert die folgende Ausgabe:

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

Was Sie hier tun, ist, dass Sie sagen, dass die erste Spalte 15 Zeichen lang und linksbündig ist und die zweite Spalte (Werte) 10 Zeichen lang und rechtsbündig ist.

Vlad Bezden
quelle
Gibt es eine Möglichkeit, die Breite der Formate zu parametrisieren? Wenn Sie in diesem Beispiel die Formatierung auf 20 und 15 Breiten ändern möchten, müssen mehrere Zeilen geändert werden. widths = [15, 10] f"{'Trades:':<width[0]}{cnt:>width[1]}",Ich möchte etwas wie oben erreichen.
Tomasz Sabała
1
Verstanden! Vielleicht findet es jemand hilfreich. Ich brauche noch eine verschachtelte Klammer dafür:f"{'Trades:':<{width[0]}}{cnt:>{width[1]}}"
Tomasz Sabała
1
Manchmal sind die besten Antworten diejenigen, die die genaue Frage nicht beantworten. Danke dafür! :)
Brian Wiley
5

Einfache Tabellierung der Ausgabe:

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

Ausgabe:

variable a    variable b
      0.33         66.67

% 10.2f: 10 ist die Mindestlänge und 2 ist die Anzahl der Dezimalstellen.

Thoran
quelle
1

So verwenden Sie die F-Zeichenfolge und steuern die Anzahl der nachgestellten Ziffern:

print(f'A number -> {my_number:>20.5f}')
Lernen ist ein Chaos
quelle