Bagaimana cara mencetak string dengan lebar tetap?

103

Saya memiliki kode ini (mencetak terjadinya semua permutasi dalam string)

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

Saya ingin mencetak semua permutasi yang ada dalam string varaible.

karena permutasi tidak memiliki panjang yang sama saya ingin memperbaiki lebar dan mencetaknya dengan cara yang tidak bagus seperti ini:

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

Bagaimana saya bisa menggunakannya format?

Saya menemukan posting ini tetapi tidak cocok dengan string alfanumerik:

format string python dengan lebar tetap

Mengatur panjang tetap dengan python

0x90
sumber
1
bagaimana dengan mencetak '% 10s'% 'mystring'
TJD
2
Terkejut karena "\t"tidak terdaftar sebagai opsi dalam solusi apa pun.

Jawaban:

113

EDIT 2013-12-11 - Jawaban ini sudah sangat tua. Ini masih valid dan benar, tetapi orang yang melihat ini harus lebih memilih sintaks format baru .

Anda dapat menggunakan pemformatan string seperti ini:

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

Pada dasarnya:

  • yang %menginformasikan karakter python itu harus pengganti sesuatu untuk tanda
  • yang smenginformasikan karakter python token akan string
  • yang 5(atau nomor apa pun yang Anda inginkan) menginformasikan python untuk pad string dengan spasi hingga 5 karakter.

Dalam kasus khusus Anda, penerapan yang mungkin terlihat seperti:

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

CATATAN SISI: Hanya ingin tahu apakah Anda mengetahui keberadaan itertoolsmodul . Misalnya Anda bisa mendapatkan daftar semua kombinasi Anda dalam satu baris dengan:

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

dan Anda bisa mendapatkan jumlah kemunculan dengan menggunakan combinationsdalam hubungannya dengan count().

Mac
sumber
24
Anda mungkin harus menyebutkan bahwa angka negatif memberikan keluaran berbantalan rata kiri; ini hampir tidak intuitif untuk pemula.
tripleee
+1 untuk @tripleee, tanpa nomor negatif Anda berikan komentar rata kiri Saya akan memukul kepala saya lebih lama ... thx m8.
Briford Wylie
Ini jauh lebih intuitif dan ringkas daripada str.format baru. Saya tidak mengerti mengapa ada dorongan python menuju konvolusi
scottmrogowski
Apakah ada cara untuk mengisi ruang kosong dengan karakter tertentu? Misalnya, jika kita perlu mencetak "05" bukan "5"
Harshit Jindal
1
Berikut beberapa trik lainnya untuk pencetakan lebar tetap yang elegan dengan f-string pada Medium .
pfabri
198

Saya merasa menggunakan str.formatjauh lebih elegan:

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

Jika Anda ingin menyelaraskan string untuk penggunaan yang tepat >bukan <:

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

Edit: Seperti yang disebutkan dalam komentar: 0 menunjukkan indeks argumen yang diteruskan ke str.format().

0x90
sumber
5
Selain itu, 0 menunjukkan posisi argumen format, sehingga Anda dapat melakukan dua hal lain: '{<5}'.format('ss') 'ss 'seperti sebelumnya, tetapi tanpa 0, melakukan hal yang sama atau 'Second {1: <5} and first {0: <5}'.format('ss', 'sss') 'Second sss and first ss 'agar Anda dapat menyusun ulang atau bahkan mengeluarkan variabel yang sama berkali-kali dalam satu keluaran tali.
mightypile
14
Saya tidak bisa lagi mengedit komentar sebelumnya, yang membutuhkannya. {<5}tidak bekerja, tetapi {: <5}tidak bekerja tanpa nilai indeks.
mightypile
9
Berikut adalah Bahasa Mini Spesifikasi Format Python yang menjelaskan string format ini dan opsi tambahan. Untuk referensi cepat, spasi di {0: <5}adalah [fill] , the <is [align], dan 5is[width]
cod3monk3y
2
5 itu bisa menjadi substitusi variabel>>> print width 20 >>> print "{0: <{width}}".format("ssssss", width=width).split('\n') ['ssssss '] >>>
pengguna2763554
4
Anda juga dapat menggunakan angka dan hanya mencantumkan variabel secara berurutan width=10; "{0: <{1}}".format('sss', width). Atau bahkan tidak '{: <{}}'.format('sss', width)
mencantumkan
72

Awalnya diposting sebagai edit untuk jawaban @ 0x90, tetapi ditolak karena menyimpang dari maksud asli postingan dan direkomendasikan untuk memposting sebagai komentar atau jawaban, jadi saya menyertakan tulisan singkat di sini.

Selain jawaban dari @ 0x90, sintaksnya dapat dibuat lebih fleksibel, dengan menggunakan variabel untuk lebar (sesuai komentar @ user2763554):

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

Lebih lanjut, Anda bisa membuat ekspresi ini lebih singkat, hanya dengan menggunakan angka dan mengandalkan urutan argumen yang diteruskan ke format:

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

Atau bahkan tinggalkan semua angka untuk kekompakan maksimal, yang berpotensi tidak implisit secara non-pythonically:

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

Perbarui 2017-05-26

Dengan pengenalan literal string yang diformat (singkatnya "f-string") di Python 3.6, sekarang dimungkinkan untuk mengakses variabel yang ditentukan sebelumnya dengan sintaks yang lebih singkat:

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

Ini juga berlaku untuk pemformatan string

>>> width=10
>>> string = 'sss'
>>> f'{string: <{width}}'
'sss       '
joelostblom
sumber
Saya sangat menyukai jawaban ini!
Syrtis Major
10

formatjelas merupakan cara yang paling elegan, tetapi afaik Anda tidak dapat menggunakannya dengan loggingmodul python , jadi inilah cara Anda melakukannya menggunakan %pemformatan:

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

Di sini, -menunjukkan rata kiri, dan angka sebelumnya smenunjukkan lebar tetap.

Beberapa keluaran sampel:

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

Info lebih lanjut di dokumen di sini: https://docs.python.org/2/library/stdtypes.html#string-formatting-operations

ryantuck
sumber
Namun ini tidak akan mempersingkat string di atas 20 karakter. Gunakan '%(name)20.20s'yang menetapkan 20 baik sebagai panjang string min maupun max!
xjcl
0
>>> print(f"{'123':<4}56789")
123 56789
Miladiouss
sumber