web-dev-qa-db-ja.com

印刷出力または文字列を固定幅にフォーマットする方法は?

私はこのコードを持っています(文字列内のすべての順列の発生を印刷します)

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文字列フォーマット

Pythonで固定長を設定する

87
0x90

EDIT 2013-12-11-この回答は非常に古いものです。まだ有効で正しいのですが、これを見ている人は 新しいフォーマット構文 を好むはずです。

次のように string formating を使用できます。

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

基本的に:

  • %文字はpythonに通知し、トークンに何かを置き換える必要があります
  • s文字はpythonにトークンが文字列であることを通知します
  • 5(または任意の数字)は、pythonに文字列に最大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

SIDE NOTE:itertools module の存在を知っているかどうか疑問に思いました。たとえば、次のようにすべての組み合わせのリストを1行で取得できます。

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

また、combinationscount()と組み合わせて使用​​すると、発生回数を取得できます。

94
mac

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はフォーマット引数のインデックスを示します。

168
0x90

元々は@ 0x90の回答の編集として投稿されましたが、投稿の元の意図から逸脱しているため拒否され、コメントまたは回答として投稿することを推奨されたため、短い記事を含めますこちら

@ 0x90からの回答に加えて、幅の変数を使用することで、構文をより柔軟にすることができます(@ user2763554のコメントによる)。

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

さらに、数字のみを使用し、formatに渡される引数の順序に依存することで、この式を簡潔にすることができます。

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

または、最大の、潜在的にPythonではない暗黙のコンパクトさのために、すべての数値を省略します。

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

更新2017-05-26

Python 3.6で フォーマットされた文字列リテラルの導入 (略して "f-strings")を使用すると、以前定義された変数に簡単な構文でアクセスできるようになりました。

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

これは文字列のフォーマットにも適用されます

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

formatは間違いなく最もエレガントな方法ですが、pythonのloggingモジュールでは使用できないので、ここでは%フォーマットを使用してそれを行う方法を示します。

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

8
Ryan Tuck