Як надрукувати рядок з фіксованою шириною?


103

У мене є цей код (друк появи всіх перестановок у рядку)

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

Я хочу надрукувати все виникнення перестановки, яке є змінним рядка.

так як перестановка не однакової довжини, я хочу зафіксувати ширину і надрукувати її в симпатичній не такій, як ця:

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

Як я можу formatце зробити?

Я знайшов ці публікації, але це не вдалося з буквено-цифровими рядками:

форматування рядка python фіксованої ширини

Встановлення фіксованої довжини за допомогою пітона


1
як щодо друку '% 10s'% 'mystring'
TJD

2
Здивований, що "\t"не вказаний як варіант у жодному рішенні.

Відповіді:


113

EDIT 2013-12-11 - Ця відповідь дуже стара. Він все ще дійсний і правильний, але люди, які дивляться на це, повинні віддавати перевагу синтаксису нового формату .

Ви можете використовувати форматування рядків так:

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

В основному:

  • як %повідомляє характер Python він повинен буде замінник що - то знак
  • в sсимвольних повідомляє пітон маркера буде рядок
  • 5(Або будь-який номер , який ви хочете) повідомляє пітон роздути рядок з пробілами до 5 символів.

У вашому конкретному випадку можлива реалізація може виглядати так:

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

БІЛЬНА ПРИМІТКА: Просто цікаво, чи знаєте ви про існування itertoolsмодуля . Наприклад, ви можете отримати список усіх своїх комбінацій в одному рядку з:

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

і ви могли отримати кількість подій, використовуючи combinationsспільно з count().


24
Можливо, ви повинні згадати, що від'ємні числа дають виправданий ліворуч вихід; це навряд чи інтуїтивно зрозуміло для початківця.
tripleee

+1 для @tripleee, без ваших негативних цифр дайте виправданий коментар зліва, я б бив головою довше ... thx m8.
Бріфорд Уайлі

Це набагато більш інтуїтивно та стисло, ніж новий str.format. Я не розумію, чому є цей поштовх пітона до згортання
scottmrogowski

Чи є спосіб заповнити порожні пробіли певним символом? Наприклад, якщо нам потрібно надрукувати "05" замість "5"
Харшит Джиндал

1
Ось ще кілька хитрощів для вишуканого друку фіксованої ширини з f-рядками на Medium .
pfabri

198

Я вважаю, що використовую str.formatнабагато елегантніше:

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

Якщо ви хочете вирівняти рядок за правильним використанням, >а не <:

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

Редагувати: Як зазначено в коментарях: 0 вказує на індекс аргументу, переданий до str.format().


5
Крім того, 0 вказує на позицію аргументу формату, тож ви можете зробити ще дві речі: так '{<5}'.format('ss') 'ss 'само, як і раніше, але без 0 робить те ж саме, або 'Second {1: <5} and first {0: <5}'.format('ss', 'sss') 'Second sss and first ss 'ви можете багато разів переупорядкувати або навіть вивести ту саму змінну за один вихід рядок.
могучий

14
Я більше не можу редагувати попередній коментар, який йому потрібен. {<5}не працює, але {: <5}працює без значення індексу.
могутній

9
Ось міні-мова специфікації формату Python, що описує ці рядки формату та додаткові параметри. Для швидкого ознайомлення, місце в {0: <5}- це [fill] , <є [align], і 5є[width]
cod3monk3y

2
Це 5 може бути змінною заміною>>> print width 20 >>> print "{0: <{width}}".format("ssssss", width=width).split('\n') ['ssssss '] >>>
user2763554

4
Ви також можете використовувати числа та просто перелічити змінні в порядку width=10; "{0: <{1}}".format('sss', width). Або навіть залишити цифри'{: <{}}'.format('sss', width)
joelostblom

71

Спочатку було розміщено як редагування на відповідь @ 0x90, але її відхилили за відхилення від початкового наміру публікації та рекомендували публікувати як коментар чи відповідь, тому я включаю тут коротке написання.

На додаток до відповіді від @ 0x90, синтаксис можна зробити більш гнучким, використовуючи змінну для ширини (відповідно до коментаря @ user2763554):

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

Крім того, ви можете зробити цей вираз більш коротким, використовуючи лише цифри і спираючись на порядок аргументів, переданих format:

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

Або навіть залишити всі числа для максимальної, потенційно непітонічно неявної компактності:

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

Оновлення 2017-05-26

Завдяки введенню відформатованих рядкових літералів (коротких "f-рядків") в Python 3.6 тепер можна отримати доступ до раніше визначених змінних із синтаксисом briefer:

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

Це стосується також форматування рядків

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

Мені дуже подобається ця відповідь!
Сиртіс-майор

10

formatце, безумовно, найелегантніший спосіб, але afaik ви не можете використовувати це з loggingмодулем python , тому ось як це можна зробити за допомогою %форматування:

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

Тут -вказує вирівнювання ліворуч, а число раніше sвказує на фіксовану ширину.

Деякі вибірки:

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

Більше інформації про документи тут: https://docs.python.org/2/library/stdtypes.html#string-formatting-operations


Однак це не скоротить рядки вище 20 символів. Використовуйте, '%(name)20.20s'який встановлює 20 як мінімальну, так і максимальну довжину рядка!
xjcl

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.