Come stampare una stringa in larghezza fissa?


103

Ho questo codice (stampa l'occorrenza di tutte le permutazioni in una stringa)

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));

Voglio stampare tutte le occorrenze di permutazione presenti nella stringa variabile.

poiché le permutazioni non hanno la stessa lunghezza, voglio correggere la larghezza e stamparla in un bel non come questo:

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

Come posso usarlo formatper farlo?

Ho trovato questi post ma non andavano bene con le stringhe alfanumeriche:

formattazione della stringa python a larghezza fissa

Impostazione della lunghezza fissa con python


1
che dire di print '% 10s'% 'mystring'
TJD

2
Sorpreso che "\t"non sia elencato come opzione in nessuna soluzione.

Risposte:


113

EDIT 2013-12-11 - Questa risposta è molto vecchia. È ancora valido e corretto, ma le persone che lo guardano dovrebbero preferire la nuova sintassi del formato .

Puoi usare la formattazione delle stringhe in questo modo:

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

Fondamentalmente:

  • il %personaggio informa Python che dovrà sostituire qualcosa a un token
  • il scarattere informa Python che il token sarà una stringa
  • il 5(o qualunque numero si desideri) informa Python di riempire la stringa con spazi fino a 5 caratteri.

Nel tuo caso specifico una possibile implementazione potrebbe essere simile a:

>>> 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 A LATO: Mi chiedevo solo se sei a conoscenza dell'esistenza del itertoolsmodulo . Ad esempio potresti ottenere un elenco di tutte le tue combinazioni in una riga 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']

e potresti ottenere il numero di occorrenze utilizzando combinationsinsieme a count().


24
Forse dovresti menzionare che i numeri negativi danno un output riempito giustificato a sinistra; questo è difficilmente intuitivo per un principiante.
tripleee

+1 per @tripleee, senza i tuoi numeri negativi dare un commento giustificato a sinistra avrei picchiato la testa più a lungo ... grazie m8.
Briford Wylie

Questo è molto più intuitivo e conciso del nuovo str.format. Non capisco perché ci sia questa spinta in Python verso la convoluzione
scottmrogowski

C'è un modo per riempire gli spazi vuoti con un carattere specifico? Ad esempio, se dobbiamo stampare "05" invece di "5"
Harshit Jindal

1
Ecco alcuni altri trucchi per una stampa elegante a larghezza fissa con stringhe f su Medium .
pfabri

198

Trovo l'uso str.formatmolto più elegante:

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

Se vuoi allineare la stringa a destra usa >invece di <:

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

Modifica: come menzionato nei commenti: lo 0 indica l'indice dell'argomento passato a str.format().


5
Inoltre, lo 0 indica la posizione dell'argomento del formato, quindi puoi fare altre due cose: '{<5}'.format('ss') 'ss 'proprio come prima, ma senza lo 0, fa la stessa cosa o 'Second {1: <5} and first {0: <5}'.format('ss', 'sss') 'Second sss and first ss 'così puoi riordinare o persino produrre la stessa variabile molte volte in un singolo output corda.
mightypile

14
Non riesco più a modificare il commento precedente, che ne ha bisogno. {<5}non funziona, ma {: <5}funziona senza il valore di indice.
mightypile

9
Di seguito è riportato il mini-linguaggio per la specifica del formato Python che descrive queste stringhe di formato e opzioni aggiuntive. Per una rapida {0: <5}[fill]<[align]5[width]
consultazione

2
Quel 5 può essere una sostituzione variabile>>> print width 20 >>> print "{0: <{width}}".format("ssssss", width=width).split('\n') ['ssssss '] >>>
user2763554

4
Puoi anche usare numeri ed elencare semplicemente le variabili in ordine width=10; "{0: <{1}}".format('sss', width). O addirittura tralasciare i numeri'{: <{}}'.format('sss', width)
joelostblom

71

Originariamente pubblicato come una modifica alla risposta di @ 0x90, ma è stato rifiutato per deviare dall'intento originale del post e consigliato di pubblicare come commento o risposta, quindi includo qui il breve articolo.

Oltre alla risposta da @ 0x90, la sintassi può essere resa più flessibile, utilizzando una variabile per la larghezza (come da commento di @ user2763554):

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

Inoltre, puoi rendere questa espressione più breve, utilizzando solo numeri e facendo affidamento sull'ordine degli argomenti passati a format:

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

O anche tralasciare tutti i numeri per la massima compattezza, potenzialmente non pitonicamente implicita:

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

Aggiornamento 2017-05-26

Con l'introduzione di stringhe letterali formattate ("f-strings" in breve) in Python 3.6, è ora possibile accedere a variabili definite in precedenza con una sintassi più breve:

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

Questo vale anche per la formattazione delle stringhe

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

Mi piace davvero di più questa risposta!
Syrtis Major

10

formatè sicuramente il modo più elegante, ma afaik non puoi usarlo con il loggingmodulo di python , quindi ecco come puoi farlo usando la %formattazione:

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

Qui, -indica l'allineamento a sinistra e il numero prima sindica la larghezza fissa.

Alcuni esempi di output:

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

Maggiori informazioni sui documenti qui: https://docs.python.org/2/library/stdtypes.html#string-formatting-operations


Tuttavia, ciò non accorcia le stringhe superiori a 20 caratteri. Usa '%(name)20.20s'che imposta 20 sia come lunghezza minima che massima della stringa!
xjcl

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.