¿Cómo imprimir una cadena en ancho fijo?


103

Tengo este código (imprimiendo la ocurrencia de todas las permutaciones en una cadena)

def splitter(str):
    for i in range(1, len(str)):
        start = str[0:i]
        end = str[i:]
        yield (start, end)
        for split in splitter(end):
            result = [start]
            result.extend(split)
            yield result    

el =[];

string = "abcd"
for b in splitter("abcd"):
    el.extend(b);

unique =  sorted(set(el));

for prefix in unique:
    if prefix != "":
        print "value  " , prefix  , "- num of occurrences =   " , string.count(str(prefix));

Quiero imprimir toda la ocurrencia de permutación que haya en la cadena variable.

dado que la permutación no tiene la misma longitud, quiero arreglar el ancho e imprimirlo de una manera agradable no como esta:

value   a - num of occurrences =    1
value   ab - num of occurrences =    1
value   abc - num of occurrences =    1
value   b - num of occurrences =    1
value   bc - num of occurrences =    1
value   bcd - num of occurrences =    1
value   c - num of occurrences =    1
value   cd - num of occurrences =    1
value   d - num of occurrences =    1

¿Cómo puedo usar formatpara hacerlo?

Encontré estas publicaciones pero no fueron bien con cadenas alfanuméricas:

formato de cadena de Python ancho fijo

Configuración de longitud fija con Python


1
¿qué pasa con la impresión '% 10s'% 'mystring'
— TJD

2
Sorprendido que "\t"no figura como opción en ninguna solución.

Respuestas:


113

EDITAR 2013-12-11 : esta respuesta es muy antigua. Sigue siendo válido y correcto, pero las personas que lo examinen deberían preferir la sintaxis del nuevo formato .

Puede usar un formato de cadena como este:

>>> print '%5s' % 'aa'
   aa
>>> print '%5s' % 'aaa'
  aaa
>>> print '%5s' % 'aaaa'
 aaaa
>>> print '%5s' % 'aaaaa'
aaaaa

Básicamente:

  • el %personaje le informa a Python que tendrá que sustituir algo a un token
  • el spersonaje le informa a Python que el token será una cadena
  • el 5(o el número que desee) informa a Python que rellene la cadena con espacios de hasta 5 caracteres.

En su caso específico, una posible implementación podría verse así:

>>> dict_ = {'a': 1, 'ab': 1, 'abc': 1}
>>> for item in dict_.items():
...     print 'value %3s - num of occurances = %d' % item # %d is the token of integers
... 
value   a - num of occurances = 1
value  ab - num of occurances = 1
value abc - num of occurances = 1

NOTA LATERAL: Me preguntaba si está al tanto de la existencia del itertoolsmódulo . Por ejemplo, podría obtener una lista de todas sus combinaciones en una línea con:

>>> [''.join(perm) for i in range(1, len(s)) for perm in it.permutations(s, i)]
['a', 'b', 'c', 'd', 'ab', 'ac', 'ad', 'ba', 'bc', 'bd', 'ca', 'cb', 'cd', 'da', 'db', 'dc', 'abc', 'abd', 'acb', 'acd', 'adb', 'adc', 'bac', 'bad', 'bca', 'bcd', 'bda', 'bdc', 'cab', 'cad', 'cba', 'cbd', 'cda', 'cdb', 'dab', 'dac', 'dba', 'dbc', 'dca', 'dcb']

y podría obtener el número de ocurrencias usando combinationsjunto con count().


24
Quizás debería mencionar que los números negativos dan una salida acolchada justificada a la izquierda; esto no es nada intuitivo para un principiante.
— tripleee

+1 para @tripleee, sin tus números negativos, da un comentario justificado a la izquierda, me habría estado golpeando la cabeza por más tiempo ... gracias m8.
— Briford Wylie

Esto es mucho más intuitivo y conciso que el nuevo formato str. No entiendo por qué hay este impulso en Python hacia la convolución
— scottmrogowski

¿Hay alguna forma de completar los espacios en blanco con un carácter específico? Por ejemplo, si necesitamos imprimir "05" en lugar de "5"
— Harshit Jindal

1
Aquí hay algunos trucos más para una impresión elegante de ancho fijo con cadenas de f en Medio .
— pfabri

198

Encuentro usar str.formatmucho más elegante:

>>> '{0: <5}'.format('ss')
'ss   '
>>> '{0: <5}'.format('sss')
'sss  '
>>> '{0: <5}'.format('ssss')
'ssss '
>>> '{0: <5}'.format('sssss')
'sssss'

Si desea alinear la cadena con el uso correcto en >lugar de <:

>>> '{0: >5}'.format('ss')
'   ss'

Editar: como se menciona en los comentarios: el 0 indica el índice del argumento que se pasó str.format().


5
Además, el 0 indica la posición del argumento de formato, por lo que puede hacer otras dos cosas: '{<5}'.format('ss') 'ss 'al igual que antes, pero sin el 0, hace lo mismo o 'Second {1: <5} and first {0: <5}'.format('ss', 'sss') 'Second sss and first ss 'para que pueda reordenar o incluso generar la misma variable muchas veces en una sola salida cuerda.
— mightypile

14
Ya no puedo editar el comentario anterior, que lo necesita. {<5}no funciona, pero {: <5}funciona sin el valor de índice.
— mightypile

9
Aquí está el mini-lenguaje de especificación de formato de Python que describe estas cadenas de formato y opciones adicionales. Para referencia rápida, el espacio en {0: <5}es el [fill] , el <es [align]y 5es[width]
— cod3monk3y

2
Ese 5 puede ser una sustitución variable>>> print width 20 >>> print "{0: <{width}}".format("ssssss", width=width).split('\n') ['ssssss '] >>>
— user2763554

4
También puede usar números y simplemente enumerar las variables en orden width=10; "{0: <{1}}".format('sss', width). O incluso '{: <{}}'.format('sss', width)
— omita

71

Publicado originalmente como una edición de la respuesta de @ 0x90, pero fue rechazado por desviarse de la intención original de la publicación y se recomendó publicarlo como comentario o respuesta, por lo que incluyo el breve artículo aquí.

Además de la respuesta de @ 0x90, la sintaxis se puede hacer más flexible, usando una variable para el ancho (según el comentario de @ user2763554):

width=10
'{0: <{width}}'.format('sss', width=width)

Además, puede hacer que esta expresión sea más breve, usando solo números y confiando en el orden de los argumentos pasados ​​a format:

width=10
'{0: <{1}}'.format('sss', width)

O incluso omita todos los números para una compacidad máxima, potencialmente no pitónicamente implícita:

width=10
'{: <{}}'.format('sss', width)

Actualización 2017-05-26

Con la introducción de literales de cadena formateados ("cadenas f" para abreviar) en Python 3.6, ahora es posible acceder a variables previamente definidas con una sintaxis más breve:

>>> name = "Fred"
>>> f"He said his name is {name}."
'He said his name is Fred.'

Esto también se aplica al formato de cadena

>>> width=10
>>> string = 'sss'
>>> f'{string: <{width}}'
'sss       '

¡Realmente me gusta más esta respuesta!
— Syrtis Major

10

formates definitivamente la forma más elegante, pero afaik no puede usar eso con el loggingmódulo de python , así que así es como puede hacerlo usando el %formato:

formatter = logging.Formatter(
    fmt='%(asctime)s | %(name)-20s | %(levelname)-10s | %(message)s',
)

Aquí, -indica alineación a la izquierda y el número anterior sindica el ancho fijo.

Algunos resultados de muestra:

2017-03-14 14:43:42,581 | this-app             | INFO       | running main
2017-03-14 14:43:42,581 | this-app.aux         | DEBUG      | 5 is an int!
2017-03-14 14:43:42,581 | this-app.aux         | INFO       | hello
2017-03-14 14:43:42,581 | this-app             | ERROR      | failed running main

Más información en los documentos aquí: https://docs.python.org/2/library/stdtypes.html#string-formatting-operations


Sin embargo, esto no acortará las cadenas por encima de los 20 caracteres. ¡Utilice lo '%(name)20.20s'que establece 20 como longitud de cuerda mínima y máxima!
— xjcl

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.