Formatear cadena de salida, alineación derecha


149

Estoy procesando un archivo de texto que contiene las coordenadas x, y, z

     1      128  1298039
123388        0        2
....

cada línea se delimita en 3 elementos usando

words = line.split()

Después de procesar los datos, necesito escribir las coordenadas en otro archivo txt para que los elementos de cada columna estén alineados a la derecha (así como el archivo de entrada). Cada línea está compuesta de las coordenadas.

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

¿Hay algún manipulador como std::setw()etc. en C ++ que permita establecer el ancho y la alineación?

Respuestas:


230

Pruebe este enfoque utilizando la str.formatsintaxis más reciente :

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

Y aquí se explica cómo hacerlo utilizando la %sintaxis anterior (útil para versiones anteriores de Python que no son compatibles str.format):

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

39
Observe cómo la sintaxis "antigua" es más limpia, más fácil de leer y más corta.
fyngyrz

2
Pensé que agregaría un enlace más directo que el proporcionado: docs.python.org/2/library/…
brw59

48
En resumen, no sé qué significa realmente limpiador, pero creo que "más fácil de leer" es solo porque es familiar. Si aún no está familiarizado con uno de ellos, el nuevo formato parece más fácil de leer. ".format" para el formateo de cadenas ciertamente parece más intuitivo que el porcentaje / módulo. La flecha hacia la derecha para la alineación hacia la derecha también parece bastante intuitiva.
Mark

2
@Mark Una forma en que la forma anterior es más limpia es que usa menos caracteres. Sí, con familiaridad, la nueva forma se vuelve intuitiva, pero no es más limpia y simple. La vieja forma es más intuitiva para aquellos que están acostumbrados a la sintaxis que nos llega a través del venerable lenguaje C, un lenguaje de concisión y precisión ejemplares. ¿Qué precedente hay para la nueva forma?
Stephen Boston

2
@StephenBoston Dejaré la legibilidad a los expertos, pero la nueva forma es absolutamente más limpia. Parens ya no son opcionales. % puede confundirse con un operador matemático (aunque no sea probable en contexto, pero a simple vista). La antigua forma fallaría si la palabra [n] no es del tipo esperado (cadena en este caso). La nueva forma no necesita saber cuál es el tipo entrante, siempre funciona. Limpio y sencillo. Para ser justos, nunca me sentí cómodo con el estilo printf (principalmente hice C con cout).
Zim

53

Se puede lograr mediante el uso de rjust:

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

52

Puedes alinearlo así:

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

donde >significa " alinear a la derecha " y 8es el ancho de un valor específico.

Y aquí hay una prueba:

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


       1      128  1298039
  123388        0        2

PD. *linesignifica que la linelista se desempaquetará, por lo que .format(*line)funciona de manera similar a .format(line[0], line[1], line[2])(suponiendo que linesea ​​una lista con solo tres elementos).



19

Aquí hay otra forma de cómo puede formatear usando el formato '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}",
)

Esto proporcionará el siguiente resultado:

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

Lo que está haciendo aquí es decir que la primera columna tiene 15 caracteres de longitud y está justificada a la izquierda y la segunda columna (valores) tiene 10 caracteres de longitud y está justificada a la derecha.


¿Hay alguna manera de parametrizar el ancho de los formatos? En este ejemplo, si decide cambiar el formato a 20 y 15 anchos, debe cambiar varias líneas. widths = [15, 10] f"{'Trades:':<width[0]}{cnt:>width[1]}",Me gustaría lograr algo como el anterior.
Tomasz Sabała

1
¡Entendido! Quizás alguien lo encuentre útil. Necesito un paréntesis anidado más para esto, así que:f"{'Trades:':<{width[0]}}{cnt:>{width[1]}}"
Tomasz Sabała

1
A veces las mejores respuestas son las que no responden la pregunta exacta. ¡Gracias por esto! :)
Brian Wiley

5

Tabulación simple de la salida:

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

salida:

variable a    variable b
      0.33         66.67

% 10.2f: 10 es la longitud mínima y 2 es el número de decimales.


1

Para hacerlo usando f-string y con control del número de dígitos finales:

print(f'A number -> {my_number:>20.5f}')
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.