web-dev-qa-db-fra.com

Comment formater la sortie d'impression ou la chaîne en largeur fixe?

J'ai ce code (en imprimant l'occurrence de toutes les permutations dans une chaîne)

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

Je veux imprimer toutes les occurrences de permutation présentes dans la chaîne varaible.

comme les permutations ne sont pas de la même longueur, je veux fixer la largeur et l’imprimer dans un Nice pas comme celui-ci:

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

Comment puis-je utiliser format pour le faire? 

J'ai trouvé ces articles mais cela ne s'est pas bien passé avec les chaînes alphanumériques:

format de chaîne python largeur fixe

Réglage de la longueur fixe en python

77
0x90

EDIT 2013-12-11 - Cette réponse est très ancienne. Il est toujours valide et correct, mais ceux qui le regardent devraient préférer la syntaxe nouveau format .

Vous pouvez utiliser format de chaîne comme ceci:

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

Fondamentalement:

  • le caractère % informe le python qu'il devra substituer quelque chose à un jeton
  • le caractère s informe python que le jeton sera une chaîne
  • le 5 (ou le numéro de votre choix) indique à python de compléter la chaîne avec des espaces de 5 caractères maximum.

Dans votre cas spécifique, une implémentation possible pourrait ressembler à:

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

SIDE NOTE: Je me demandais si vous étiez au courant de l’existence du module itertools . Par exemple, vous pouvez obtenir une liste de toutes vos combinaisons sur une ligne avec:

>>> [''.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']

et vous pouvez obtenir le nombre d'occurrences en utilisant combinations conjointement avec count().

89
mac

Je trouve l'utilisation de str.format beaucoup plus élégante:

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

Si vous préférez que la chaîne soit alignée correctement, utilisez > au lieu de <:

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

Edit: Comme mentionné dans les commentaires: le 0 indique l’index de l’argument de format. 

159
0x90

Initialement posté en tant que modification de la réponse de @ 0x90, mais il a été rejeté pour modification de l'intention initiale de l'article et recommandé de publier en tant que commentaire ou réponse.

En plus de la réponse de @ 0x90, la syntaxe peut être rendue plus flexible en utilisant une variable pour la largeur (selon le commentaire de @ user2763554):

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

De plus, vous pouvez rendre cette expression plus brève, en utilisant uniquement des nombres et en s’appuyant sur l’ordre des arguments passés à format:

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

Ou même laisser de côté tous les nombres pour une compacité maximale, potentiellement non implicite pythoniquement:

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

Mise à jour 2017-05-26

Avec l'introduction de littéraux de chaîne formatés ("f-strings" en abrégé) dans Python 3.6, il est maintenant possible d'accéder à des variables précédemment définies avec une syntaxe plus courte:

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

Ceci s'applique également au formatage de chaîne

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

format est certainement la méthode la plus élégante, mais vous ne pouvez certes pas l'utiliser avec le module logging de python. Voici comment procéder à l'aide du formatage %:

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

Ici, le - indique l'alignement à gauche et le nombre précédant s indique la largeur fixe.

Quelques exemples de sortie:

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

Plus d'infos sur les documents ici: https://docs.python.org/2/library/stdtypes.html#string-formatting-operations

8
Ryan Tuck