Jak wydrukować ciąg o stałej szerokości?


105

Mam ten kod (wypisuje wystąpienie wszystkich permutacji w ciągu)

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

Chcę wydrukować całe wystąpienie permutacji w zmiennej łańcuchowej.

ponieważ permutacja nie jest tej samej długości, chcę poprawić szerokość i wydrukować ją w ładnym, innym niż ten:

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

Jak mogę formatto zrobić?

Znalazłem te posty, ale nie pasowały do ​​ciągów alfanumerycznych:

Python string formatting fixed width

Ustawianie stałej długości w Pythonie


1
a co z printem '% 10s'% 'mystring'
TJD

2
Zaskoczony, że "\t"nie jest wymieniony jako opcja w żadnym rozwiązaniu.

Odpowiedzi:


115

EDYCJA 2013-12-11 - Ta odpowiedź jest bardzo stara. Nadal jest poprawny i poprawny, ale osoby, które się tym zajmują, powinny preferować nową składnię formatu .

Możesz użyć formatowania ciągów w następujący sposób:

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

Gruntownie:

  • to %informuje charakter Python będzie musiał coś zastępczego token
  • to sinformuje znaków python tokena będzie ciągiem
  • the 5(lub cokolwiek numer chcesz) informuje pyton pad napis spacjami do 5 znaków.

W Twoim konkretnym przypadku możliwa implementacja może wyglądać następująco:

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

UWAGA BOCZNA: Po prostu zastanawiałem się, czy wiesz o istnieniu itertoolsmodułu . Na przykład możesz uzyskać listę wszystkich swoich kombinacji w jednym wierszu z:

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

i możesz uzyskać liczbę wystąpień, używając combinationsw połączeniu z count().


24
Być może powinieneś wspomnieć, że liczby ujemne dają wyrównane do lewej dane wyjściowe; jest to mało intuicyjne dla początkującego.
tripleee

+1 dla @tripleee, bez twoich liczb ujemnych podaj komentarz wyrównany do lewej, uderzyłbym mnie w głowę dłużej ... thx m8.
Briford Wylie

Jest to znacznie bardziej intuicyjne i zwięzłe niż nowy format str.format. Nie rozumiem, dlaczego jest to pchnięcie w Pythonie w kierunku splotu
scottmrogowski

Czy istnieje sposób na wypełnienie pustych miejsc określonym znakiem? Na przykład, jeśli musimy wydrukować „05” zamiast „5”
Harshit Jindal

1
Oto kilka innych sztuczek dotyczących eleganckiego drukowania o stałej szerokości za pomocą f-stringów na Medium .
pfabri

201

Uważam, że użycie str.formatznacznie bardziej eleganckiego:

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

Jeśli chcesz wyrównać ciąg do prawej strony, >zamiast <:

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

Edycja: jak wspomniano w komentarzach: 0 wskazuje indeks argumentu przekazany do str.format().


5
Dodatkowo 0 wskazuje pozycję argumentu formatu, więc możesz zrobić dwie inne rzeczy: '{<5}'.format('ss') 'ss 'tak jak poprzednio, ale bez 0, robi to samo lub 'Second {1: <5} and first {0: <5}'.format('ss', 'sss') 'Second sss and first ss 'możesz zmienić kolejność lub nawet wyprowadzić tę samą zmienną wiele razy w jednym wyjściu strunowy.
mightypile

14
Nie mogę już edytować poprzedniego komentarza, który tego potrzebuje. {<5}nie działa, ale {: <5}działa bez wartości indeksu.
mightypile

9
Oto mini-język specyfikacji formatu Python opisujący te ciągi formatujące i dodatkowe opcje. Dla szybkiego odniesienia, przestrzeń w {0: <5}to [fill] , <jest [align]i 5jest[width]
cod3monk3y

2
To 5 może być podstawieniem zmiennej>>> print width 20 >>> print "{0: <{width}}".format("ssssss", width=width).split('\n') ['ssssss '] >>>
user2763554

4
Możesz także użyć liczb i po prostu wymienić zmienne w kolejności width=10; "{0: <{1}}".format('sss', width). Lub nawet pomiń liczby'{: <{}}'.format('sss', width)
joelostblom

74

Pierwotnie opublikowany jako zmiana odpowiedzi @ 0x90, ale został odrzucony za odbieganie od pierwotnego zamysłu postu i zalecany jako komentarz lub odpowiedź, więc dołączam tutaj krótki opis.

Oprócz odpowiedzi z @ 0x90, składnię można uelastycznić, używając zmiennej dla szerokości (zgodnie z komentarzem @ user2763554):

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

Co więcej, możesz skrócić to wyrażenie, używając tylko liczb i polegając na kolejności argumentów przekazywanych do format:

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

Lub nawet pomiń wszystkie liczby, aby uzyskać maksymalną, potencjalnie niejawną w Pythonie zwartość:

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

Aktualizacja 2017-05-26

Wraz z wprowadzeniem sformatowanych literałów łańcuchowych (w skrócie „f-strings”) w Pythonie 3.6, jest teraz możliwy dostęp do wcześniej zdefiniowanych zmiennych przy użyciu krótszej składni:

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

Dotyczy to również formatowania ciągów

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

Bardzo podoba mi się ta odpowiedź!
Syrtis Major

10

formatjest zdecydowanie najbardziej eleganckim sposobem, ale afaik, nie możesz tego użyć z loggingmodułem Pythona , więc oto jak możesz to zrobić używając %formatowania:

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

W tym przypadku -symbol wskazuje wyrównanie do lewej, a liczba przed swskazuje stałą szerokość.

Niektóre przykładowe dane wyjściowe:

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

Więcej informacji w dokumentach tutaj: https://docs.python.org/2/library/stdtypes.html#string-formatting-operations


Nie spowoduje to jednak skrócenia ciągów powyżej 20 znaków. Użyj, '%(name)20.20s'który ustawia 20 zarówno jako minimalną, jak i maksymalną długość łańcucha!
xjcl

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.